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;
}