RGB565保存为bmp的代码

版权声明:本文为博主原创文章,未经博主允许不得转载。转载请标注出处: https://blog.csdn.net/sheji105/article/details/81705434
/**
RGB introduce:
https://baike.baidu.com/item/BMP/35116?fr=aladdin
https://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html
WINGDI.h
**/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define BI_BITFIELDS 0x3

typedef char BYTE;
typedef short WORD;
typedef int DWORD;
typedef int LONG;

typedef struct tagBITMAPFILEHEADER{
	WORD bfType;//位图文件的类型,在Windows中,此字段的值总为‘BM’(1-2字节)
	DWORD bfSize;//位图文件的大小,以字节为单位(3-6字节,低位在前)
	WORD bfReserved1;//位图文件保留字,必须为0(7-8字节)
	WORD bfReserved2;//位图文件保留字,必须为0(9-10字节)
	DWORD bfOffBits;//位图数据的起始位置,以相对于位图(11-14字节,低位在前)
	//文件头的偏移量表示,以字节为单位
}__attribute__((packed)) BitMapFileHeader;	//BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
	DWORD biSize;//本结构所占用字节数(15-18字节)
	LONG biWidth;//位图的宽度,以像素为单位(19-22字节)
	LONG biHeight;//位图的高度,以像素为单位(23-26字节)
	WORD biPlanes;//目标设备的级别,必须为1(27-28字节)
	WORD biBitCount;//每个像素所需的位数,必须是1(双色),(29-30字节)
	//4(16色),8(256色)16(高彩色)或24(真彩色)之一
	DWORD biCompression;//位图压缩类型,必须是0(不压缩),(31-34字节)
	//1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
	DWORD biSizeImage;//位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
	LONG biXPelsPerMeter;//位图水平分辨率,像素数(39-42字节)
	LONG biYPelsPerMeter;//位图垂直分辨率,像素数(43-46字节)
	DWORD biClrUsed;//位图实际使用的颜色表中的颜色数(47-50字节)
	DWORD biClrImportant;//位图显示过程中重要的颜色数(51-54字节)
}__attribute__((packed)) BitMapInfoHeader;	//BITMAPINFOHEADER;


typedef struct tagRGBQUAD{
	BYTE rgbBlue;//蓝色的亮度(值范围为0-255)
	BYTE rgbGreen;//绿色的亮度(值范围为0-255)
	BYTE rgbRed;//红色的亮度(值范围为0-255)
	BYTE rgbReserved;//保留,必须为0
}__attribute__((packed)) RgbQuad;	//RGBQUAD;





int Rgb565ConvertBmp(char *buf,int width,int height, const char *filename)
{
	FILE* fp;

	BitMapFileHeader bmfHdr; //定义文件头
	BitMapInfoHeader bmiHdr; //定义信息头
	RgbQuad bmiClr[3]; //定义调色板

	bmiHdr.biSize = sizeof(BitMapInfoHeader);
	bmiHdr.biWidth = width;//指定图像的宽度,单位是像素
	bmiHdr.biHeight = height;//指定图像的高度,单位是像素
	bmiHdr.biPlanes = 1;//目标设备的级别,必须是1
	bmiHdr.biBitCount = 16;//表示用到颜色时用到的位数 16位表示高彩色图
	bmiHdr.biCompression = BI_BITFIELDS;//BI_RGB仅有RGB555格式
	bmiHdr.biSizeImage = (width * height * 2);//指定实际位图所占字节数
	bmiHdr.biXPelsPerMeter = 0;//水平分辨率,单位长度内的像素数
	bmiHdr.biYPelsPerMeter = 0;//垂直分辨率,单位长度内的像素数
	bmiHdr.biClrUsed = 0;//位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)
	bmiHdr.biClrImportant = 0;//说明对图象显示有重要影响的颜色索引的数目,0表示所有颜色都重要

	//RGB565格式掩码
	bmiClr[0].rgbBlue = 0;
	bmiClr[0].rgbGreen = 0xF8;
	bmiClr[0].rgbRed = 0;
	bmiClr[0].rgbReserved = 0;

	bmiClr[1].rgbBlue = 0xE0;
	bmiClr[1].rgbGreen = 0x07;
	bmiClr[1].rgbRed = 0;
	bmiClr[1].rgbReserved = 0;

	bmiClr[2].rgbBlue = 0x1F;
	bmiClr[2].rgbGreen = 0;
	bmiClr[2].rgbRed = 0;
	bmiClr[2].rgbReserved = 0;


	bmfHdr.bfType = (WORD)0x4D42;//文件类型,0x4D42也就是字符'BM'
	bmfHdr.bfSize = (DWORD)(sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader) + sizeof(RgbQuad) * 3 + bmiHdr.biSizeImage);//文件大小
	bmfHdr.bfReserved1 = 0;//保留,必须为0
	bmfHdr.bfReserved2 = 0;//保留,必须为0
	bmfHdr.bfOffBits = (DWORD)(sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader)+ sizeof(RgbQuad) * 3);//实际图像数据偏移量

	if (!(fp = fopen(filename, "wb"))){
		return -1;
	} else {
		printf("file %s open success\n",filename);
	}

	fwrite(&bmfHdr, 1, sizeof(BitMapFileHeader), fp); 
	fwrite(&bmiHdr, 1, sizeof(BitMapInfoHeader), fp); 
	fwrite(&bmiClr, 1, 3*sizeof(RgbQuad), fp);

//	fwrite(buf, 1, bmiHdr.biSizeImage, fp);	//mirror
	for(int i=0; i<height; i++){
		fwrite(buf+(width*(height-i-1)*2), 2, width, fp);
	}

	printf("Image size=%d, file size=%d, width=%d, height=%d\n", bmiHdr.biSizeImage, bmfHdr.bfSize, width, height);
	printf("%s over\n", __FUNCTION__);
	fclose(fp);

	 return 0;
}

猜你喜欢

转载自blog.csdn.net/sheji105/article/details/81705434