直接上代码,根据不同需求可以进行改动
#include <stdio.h>
#include <iostream>
using namespace std;
/
//读写图像文件的结构和函数的定义
/
// 文件头信息, 14 字节
struct sBMPFileHeader
{
unsigned short usImageType;//位图文件的类型,必须为BM(1-2字节)
unsigned short ulFsize1,ulFsize2;//位图文件的大小,以字节为单位(3-6字节,低位在前)
unsigned short usReserved1;//位图文件保留字,必须为0(7-8字节)
unsigned short usReserved2;//位图文件保留字,必须为0(9-10字节)
unsigned short ulBMPDateOffset1,ulBMPDateOffset2;//位图数据的起始位置,以相对于位图(11-14字节,低位在前)
//文件头的偏移量表示,以字节为单位
#ifdef _WIN32
};
#else
}__attribute__((packed));
#endif
// BMP信息头,40个字节
struct sBMPInfoHeader
{
unsigned int biSize; //本结构所占用字节数(15-18字节)
int biWidth; //位图的宽度,以像素为单位(19-22字节)
int biHeight; //位图的高度,以像素为单位(23-26字节)
unsigned short biPlanes; //目标设备的级别,必须为1(27-28字节)
unsigned short biBitCount; //每个像素所需的位数,必须是1(双色),(29-30字节) 4(16色),8(256色)16(高彩色)或24(真彩色)之一
unsigned int biCompression; //位图压缩类型,必须是0(不压缩),(31-34字节) 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
unsigned int biSizeImage; //位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
int biXPelsPerMeter; //位图水平分辨率,每米像素数(39-42字节)
int biYPelsPerMeter; //位图垂直分辨率,每米像素数(43-46字节)
unsigned int biClrUsed; //位图实际使用的颜色表中的颜色数(47-50字节)
unsigned int biClrImportant; //位图显示过程中重要的颜色数(51-54字节)
#ifdef _WIN32
};
#else
}__attribute__((packed));
#endif
//颜色表
struct sBMPColorQuad
{
unsigned char rgbBlue; //蓝色的亮度(值范围为0-255)
unsigned char rgbGreen; //绿色的亮度(值范围为0-255)
unsigned char rgbRed; //红色的亮度(值范围为0-255)
unsigned char rgbReserved;//保留,必须为0
#ifdef _WIN32
};
#else
}__attribute__((packed));
#endif
struct sBMPData
{
unsigned int width, height;
unsigned int lBitNum;
#ifdef _WIN32
unsigned char *data = NULL;
#else
unsigned char *data;
#endif
};
int SaveImage(const char *pcFileName, unsigned char *pucImage, int iWidth, int iHeight)
{
char pcTMP[255];
#ifdef _WIN32
sprintf(pcTMP, "d:\\%s", pcFileName);
#else
sprintf(pcTMP, "%s", pcFileName);
#endif
FILE *bmp_file;
//打开文件
if (!(bmp_file = fopen(pcTMP, "wb")))
return 1;
int i;
int iWidthNew_1 = iWidth;
if ((iWidth % 4) != 0)
iWidthNew_1 = (iWidth >> 2) << 2;
int iCut_1 = iWidth - iWidthNew_1;
unsigned char *pucTTTTT = new unsigned char[iWidthNew_1 * iHeight];
unsigned char* pucOld = pucImage, *pucNew = pucTTTTT + iWidthNew_1 * (iHeight - 1);
for (i = 0; i<iHeight; i++, pucOld += iWidth, pucNew -= iWidthNew_1) //将图像裁剪并在y方向翻转
memcpy(pucNew, pucOld, iWidthNew_1);
sBMPData sbmpData;
sbmpData.width = iWidthNew_1;
sbmpData.height = iHeight;
sbmpData.lBitNum = 8;
sbmpData.data = pucTTTTT;
struct sBMPFileHeader bmp_file_header;
struct sBMPInfoHeader bmp_info_header;
struct sBMPColorQuad bmp_color_quad[256];
if (sbmpData.lBitNum == 8)
{
bmp_file_header.usImageType = 0x4D42;//位图文件的类型,必须为BM(1-2字节)
bmp_file_header.ulFsize1 = (unsigned short)(sbmpData.width*sbmpData.height + 0x0436);//位图文件的大小,以字节为单位(3-4字节,低位在前)
bmp_file_header.ulFsize2 = (unsigned short)((sbmpData.width*sbmpData.height + 0x0436) >> 16);//位图文件的大小,以字节为单位(5-6字节,高位在后)
bmp_file_header.ulBMPDateOffset1 = 0x0436; //位图数据的起始位置,以相对于位图(11-12字节,低位在前)
bmp_file_header.ulBMPDateOffset2 = 0x00; //位图数据的起始位置,以相对于位图(13-14字节,高位在后)
bmp_info_header.biSize = 0x28; //本结构所占用字节数(15-18字节)
bmp_info_header.biWidth = sbmpData.width; //位图的宽度,以像素为单位(19-22字节)
bmp_info_header.biHeight = sbmpData.height; //位图的高度,以像素为单位(23-26字节)
bmp_info_header.biPlanes = 1; //目标设备的级别,必须为1(27-28字节)
bmp_info_header.biBitCount = 8;//每个像素所需的位数,必须是1(双色),(29-30字节)
bmp_info_header.biCompression = 0; //0x00 位图压缩类型,必须是0(不压缩)
bmp_info_header.biSizeImage = 0x00;//位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
bmp_info_header.biXPelsPerMeter = 0x0b40;//位图水平分辨率,每米像素数(39-42字节)
bmp_info_header.biYPelsPerMeter = 0x0b40;//位图垂直分辨率,每米像素数(43-46字节)
bmp_info_header.biClrUsed = 0x0100;//位图实际使用的颜色表中的颜色数(47-50字节)
bmp_info_header.biClrImportant = 0;//位图显示过程中重要的颜色数(51-54字节)
for (i = 0; i<256; i++)
{
bmp_color_quad[i].rgbBlue = (unsigned char)i;//蓝色的亮度(值范围为0-255)
bmp_color_quad[i].rgbGreen = (unsigned char)i;//绿色的亮度(值范围为0-255)
bmp_color_quad[i].rgbRed = (unsigned char)i; //红色的亮度(值范围为0-255)
bmp_color_quad[i].rgbReserved = 0;//保留,必须为0
}
}
else if (sbmpData.lBitNum == 24)
{
bmp_file_header.usImageType = 0x4D42;
bmp_file_header.ulFsize1 = (unsigned short)(sbmpData.width*sbmpData.height * 3 + 0x0036);
bmp_file_header.ulFsize2 = (unsigned short)((sbmpData.width*sbmpData.height * 3 + 0x0036) >> 16);
bmp_file_header.ulBMPDateOffset1 = 0x0036;
bmp_file_header.ulBMPDateOffset2 = 0x00;
bmp_info_header.biSize = 0x28;
bmp_info_header.biWidth = sbmpData.width;
bmp_info_header.biHeight = sbmpData.height;
bmp_info_header.biPlanes = 1;
bmp_info_header.biBitCount = 24;
bmp_info_header.biCompression = 0; //0x00
bmp_info_header.biSizeImage = 0x00;
bmp_info_header.biXPelsPerMeter = 0x0b40;
bmp_info_header.biYPelsPerMeter = 0x0b40;
bmp_info_header.biClrUsed = 0x0000;
bmp_info_header.biClrImportant = 0;
}
else if (sbmpData.lBitNum == 16)
{
bmp_file_header.usImageType = 0x4D42;
bmp_file_header.ulFsize1 = (unsigned short)(sbmpData.width*sbmpData.height * 2 + 0x0036);
bmp_file_header.ulFsize2 = (unsigned short)((sbmpData.width*sbmpData.height * 2 + 0x0036) >> 16);
bmp_file_header.ulBMPDateOffset1 = 0x0036;
bmp_file_header.ulBMPDateOffset2 = 0x00;
bmp_info_header.biSize = 0x28;
bmp_info_header.biWidth = sbmpData.width;
bmp_info_header.biHeight = sbmpData.height;
bmp_info_header.biPlanes = 1;
bmp_info_header.biBitCount = 16;
bmp_info_header.biCompression = 0; //0x00
bmp_info_header.biSizeImage = 0x00;
bmp_info_header.biXPelsPerMeter = 0x0b40;
bmp_info_header.biYPelsPerMeter = 0x0b40;
bmp_info_header.biClrUsed = 0x0000;
bmp_info_header.biClrImportant = 0;
}
//写文件头
fwrite(&bmp_file_header, sizeof bmp_file_header, 1, bmp_file);
//写信息头
fwrite(&bmp_info_header, sizeof bmp_info_header, 1, bmp_file);
//写图片数据
if (sbmpData.lBitNum == 8)
{
for (i = 0; i<256; i++)
fwrite(&bmp_color_quad[i], sizeof(bmp_color_quad[i]), 1, bmp_file);
fwrite(sbmpData.data, sbmpData.width * sbmpData.height, 1, bmp_file);
}
else if (sbmpData.lBitNum == 24)
fwrite(sbmpData.data, sbmpData.width * sbmpData.height * 3, 1, bmp_file);
else if (sbmpData.lBitNum == 16)
fwrite(sbmpData.data, sbmpData.width * sbmpData.height * 2, 1, bmp_file);
//关闭文件
fclose(bmp_file);
delete[] pucTTTTT;
return 0;
}