【数字图像处理】——BMP文件的简单操作

1、在 VC 环境下 – 建立动态库工程,录入 HXLBMPFILE 类,建立相应动态库,将整个类作为动态库输出。

输出 HXLBMPFILE.dll/lib 。可参考动态库如何建立
录入 hxlbmpfile.h 文件,包含 HXLBMPFILE 类 的定义

#pragma once

#include"stdio.h"
#include"math.h"
#include"windows.h"
#include<iostream>
using namespace std;

#ifndef HXLBMPFILEH
#define HXLBMPFILEH

class _declspec(dllexport) HXLBMPFILE 
{
	BYTE *Imagedata;//位图数据域
public:
	int imagew;//图片的宽度
	int imageh;//图片的高度
	int iYRGBnum;//1:灰度,3:彩色

	RGBQUAD palette[256];//调色板

	 BYTE *pDataAt(int h, int Y0R0G1B2 = 0);//指向图像第h行的位置,Y0R0G1B2表示:灰度(Y)=0,R=0,G=1,B=2
	 BOOL AllocateMem();//为图像分配内存

	 BOOL LoadBMPFILE(const char *fname);
	 BOOL SaveBMPFILE(const char *fname);

	 HXLBMPFILE();
	 ~HXLBMPFILE();
};
#endif

录入 hxlbmpfile.cpp 文件,包含 HXLBMPFILE 类的实现

#include "stdafx.h"
#include "HXLBMPFILE.h"
//#define _CRT_SECURE_NO_WARNINGS
//#define _CRT_SECURE_NO_DEPRECATE
#pragma warning(disable:4996);

HXLBMPFILE::HXLBMPFILE() {
	Imagedata = NULL;
	for (int i = 0; i < 256; i++) {
		palette[i].rgbBlue = i;
		palette[i].rgbGreen = i;
		palette[i].rgbRed = i;
		palette[i].rgbReserved = 0;
	};
	iYRGBnum = 0;
	imagew = imageh = 0;

};


HXLBMPFILE::~HXLBMPFILE() {
	if (Imagedata)delete[]Imagedata;
};

BYTE  *HXLBMPFILE::pDataAt(int h, int Y0R0G1B2) {
	if (iYRGBnum <= Y0R0G1B2)return NULL;
	int w = imagew * h + Y0R0G1B2 * imagew*imageh;
	return Imagedata + w;
};

BOOL HXLBMPFILE::AllocateMem() {
	int w = imagew * imageh*iYRGBnum;
	if (Imagedata) {
		delete[] Imagedata;
		Imagedata = NULL;
	};
	Imagedata = new BYTE[w];
	if (Imagedata) memset(Imagedata, 0, w);
	return (Imagedata != NULL);
};

BOOL HXLBMPFILE::LoadBMPFILE(const char *cFilename) {
	FILE *f;
	if (strlen(cFilename) < 1) return FALSE;

	f = fopen(cFilename, "r+b");
	if (f == NULL)return FALSE;

	BITMAPFILEHEADER fh;
	BITMAPINFOHEADER ih;

	fread(&fh, sizeof(BITMAPFILEHEADER), 1, f);
	if (fh.bfType != 0x4d42) {
		fclose(f);
		return FALSE;
	};

	fread(&ih, sizeof(BITMAPINFOHEADER), 1, f);
	if ((ih.biBitCount != 8) && (ih.biBitCount != 24)) {
		fclose(f);
		return FALSE;
	};

	iYRGBnum = ih.biBitCount / 8;
	imagew = ih.biWidth;
	imageh = ih.biHeight;

	if (!AllocateMem()) {
		fclose(f);
		return FALSE;
	};
	if (iYRGBnum == 1) {
		fread(palette, sizeof(RGBQUAD), 256, f);
	};
	fseek(f, fh.bfOffBits, SEEK_SET);
	int w4b = (imagew*iYRGBnum + 3) / 4 * 4, i, j;
	BYTE *ptr;

	ptr = new BYTE[w4b];
	if (ptr == NULL) {
		fclose(f);
		return FALSE;
	};
	if (iYRGBnum == 1) {
		for (i = imageh - 1; i >= 0; i--) {
			fread(ptr, w4b, 1, f);
			memmove(pDataAt(i), ptr, imagew);
		}
	}
	if (iYRGBnum == 3) {
		for (i = imageh - 1; i >= 0; i--)
		{
			fread(ptr, w4b, 1, f);
			for (j = 0; j < imagew; j++)	
			{
				*(pDataAt(i, 0) + j) = *(ptr + j * 3 + 2);
				*(pDataAt(i, 1) + j) = *(ptr + j * 3 + 1);
				*(pDataAt(i, 2) + j) = *(ptr + j * 3 + 0);
			}
		}
	}
	delete[]ptr;
	fclose(f);
	return TRUE;
};

BOOL HXLBMPFILE::SaveBMPFILE(const char *cFilename) {
	if (!Imagedata)return FALSE;
	FILE *f;
	if (strlen(cFilename) < 1)return FALSE;
	f = fopen(cFilename, "w+b");
	if (f == NULL)return FALSE;

	BITMAPFILEHEADER fh;
	BITMAPINFOHEADER ih;
	memset(&ih, 0, sizeof(BITMAPINFOHEADER));

	fh.bfType = 0x4d42;
	fh.bfReserved1 = fh.bfReserved2 = 0;
	fh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ((iYRGBnum == 1) ? 256 * sizeof(RGBQUAD) : 0);
	ih.biSize = 40;
	ih.biPlanes = 1;
	ih.biWidth = imagew;
	ih.biHeight = imageh;
	ih.biBitCount = 8 * iYRGBnum;//iRGBnum

	int w4b = (imagew*iYRGBnum + 3) / 4 * 4;//iRGBnum
	ih.biSizeImage = ih.biHeight*w4b;
	fh.bfSize = fh.bfOffBits + ih.biSizeImage;

	fwrite(&fh, sizeof(BITMAPFILEHEADER), 1, f);
	fwrite(&ih, sizeof(BITMAPINFOHEADER), 1, f);
	if (iYRGBnum == 1)fwrite(palette, sizeof(RGBQUAD), 256, f);//iRGBnum

	BYTE* ptr;
	int i, j;
	ptr = new BYTE[w4b];
	if (ptr == NULL) {
		fclose(f);
		return FALSE;
	}
	memset(ptr, 0, w4b);
	if (iYRGBnum == 1) {
		for (i = ih.biHeight - 1; i >= 0; i--) {
			memmove(ptr, pDataAt(i), ih.biWidth);
			fwrite(ptr, w4b, 1, f);
		}
	}
	if (iYRGBnum == 3) {
		for (i = ih.biHeight - 1; i >= 0; i--) {
			for (j = 0; j < ih.biWidth; j++) {
				*(ptr + j * 3 + 0) = *(pDataAt(i, 2) + j);
				*(ptr + j * 3 + 1) = *(pDataAt(i, 1) + j);
				*(ptr + j * 3 + 2) = *(pDataAt(i, 0) + j);
			}
			fwrite(ptr, w4b, 1, f);
		}
	}
	delete[]ptr;
	fclose(f);
	return TRUE;
}

2、录入主函数(根据需要注释某段代码段)
int main()
{
	HXLBMPFILE bmpfile;
	if (!bmpfile.LoadBMPFILE("1.bmp")) return 1;
	cout << "bmpfile.iYRGBnum=" << bmpfile.iYRGBnum << endl;

	HXLBMPFILE bf;
	bf.imagew = bmpfile.imagew;
	bf.imageh = bmpfile.imageh;
	bf.iYRGBnum =bmpfile.iYRGBnum;//toGrey函数需将此值替换为1
	if (!bf.AllocateMem())return 1;
//ReverseWhite(bf, bmpfile);//反白函数
//bf.SaveBMPFILE("ReverseWhite.bmp");//反白图的存储

//Pallette(bmpfile);//改变调色板函数
//bmpfile.SaveBMPFILE("Pallette.bmp");//改变调色板后图的存储

//toGrey(bf, bmpfile);//彩色变灰度图像函数
//bf.SaveBMPFILE("toGrey.bmp");//新的灰度图像的存储

//	toTxt(bmpfile);//将图像数据转为txt文件


	cout << "program ends! " << endl;
	return 0;
   
}

3、反白函数
//反白函数
void ReverseWhite(HXLBMPFILE &bf, HXLBMPFILE &bmpfile) //bf反白后的图像,bmpfile原图像
{
	cout << "这是反白函数" << endl;
	//cout << "bmpfile.iYRGBnum=" << bmpfile.iYRGBnum << endl;
	if (bmpfile.iYRGBnum == 1) {
		for (int i = 0; i < bmpfile.imageh; i++) {
				for (int j = 0; j < bmpfile.imagew; j++) {
					bf.pDataAt(i)[j] = 255 - bmpfile.pDataAt(i)[j];
				}
			}
	}
	else {
		for (int i = 0; i < bmpfile.imageh; i++) {
			for (int j = 0; j < bmpfile.imagew; j++)
						{
							bf.pDataAt(i, 0)[j] = 255 - bmpfile.pDataAt(i, 0)[j];
							bf.pDataAt(i, 1)[j] = 255 - bmpfile.pDataAt(i, 1)[j];
							bf.pDataAt(i, 2)[j] = 255 - bmpfile.pDataAt(i, 2)[j];
						}
		}
			
	}
	
}
4、改变调色板的颜色值,看对图像的影响
//改变调色板函数
void Pallette(HXLBMPFILE &bmpfile) {
	cout << "这是改变调色板的函数" << endl;
	for (int i = 0; i < 256; i++) {
			bmpfile.palette[i].rgbRed = i;//此值可随意改变
			bmpfile.palette[i].rgbGreen = 10*i;
			bmpfile.palette[i].rgbBlue = 2*i;
	}
}
5、将彩色图像变为灰度图象
将彩色图像变为灰度图像
void toGrey(HXLBMPFILE &bf, HXLBMPFILE &bmpfile) {
	cout << "这是将彩色图像变为灰度图像的函数" << endl;
	cout << "bmpfile.iYRGBnum=" <<bmpfile.iYRGBnum << endl;
	int i, j;
		for (i = 0; i < bmpfile.imageh; i++) {
			for (j = 0; j < bmpfile.imagew; j++)
			{
            	//bf.pDataAt(i)[j] = bmpfile.pDataAt(i, 0)[j] * 0.299 + bmpfile.pDataAt(i, 1)[j] * 0.587 + (float)bmpfile.pDataAt(i, 2)[j] * 0.114;
				//上下两种格式都可
                bf.pDataAt(i)[j] = int((float)bmpfile.pDataAt(i, 0)[j] * 0.299 + (float)bmpfile.pDataAt(i, 1)[j] * 0.587 + (float)bmpfile.pDataAt(i, 2)[j] * 0.114);         
			}
		}
}
6、在 excel 中可视化图像数据

编程实现:将一灰度图像数据变成文本格式存 储到 bmp.txt 中,txt 文件的一行对应图像的一 行,按图像显示的顺序存储。将 bmp.txt 调入到 excel 中。 用excel的至少3种可视化工具(如曲线显示等)将 bmp.txt 图形化显示。

bool toTxt(HXLBMPFILE &bmpfile)	//将bmp数据存入txt
{

	FILE *file;
	if ((file = fopen("bmp.txt", "w+")) == NULL)//新建一个文本文件,已存在的文件将内容清空,允许读写
	{
		return false;
	}
	for (int i = 0; i < bmpfile.imageh; i++)	
	{
		for (int j = 0; j < bmpfile.imagew; j++)
		{
			fprintf(file, "%4d", bmpfile.pDataAt(i)[j]);//写入整型数值,宽度为4
		}
		fprintf(file, "\n");//按行写入,换行
	}
	fclose(file);
	return true;
}
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值