此代码的功能是传入BMP格式的数据,传出提取的RGB数据。BMP图像支持8bit、16bit、24bit、32bit的格式,得到的都是24bit的RGB格式图像,如果想得到YUV格式的图像,可以将得到RGB再转为YUV格式。RGB转YUV格式参考博客《C语言实现RGB packet格式转YUV(NV21)格式》

//BMP图片的压缩方式 #define BI_RGB          (0) #define BI_BITFIELDS         (3)  //RGB555的掩码 #define RGB555_RED_MASK        (31744) #define RGB555_GREEN_MASK       (992) #define RGB555_BLUE_MASK       (31)  //RGB565的掩码 #define RGB565_RED_MASK        (63488) #define RGB565_GREEN_MASK       (2016) #define RGB565_BLUE_MASK       (31)  //BMP图片的像素位数 #define BMP_8_BIT          (8) #define BMP_16_BIT         (16) #define BMP_24_BIT         (24) #define BMP_32_BIT         (32)  //16位BMP图片从文件头到图像数据的偏移量 #define BMP_16_BIT_BI_BITFIELDS_OFFSET    (66) #define BMP_16_BIT_BI_RGB_OFFSET     (54)  //8位BMP图片调色板的大小 #define BMP_8_BIT_OFFSET       (1024)  //BMP图片的文件头,固定14字节 #define BMP_FILE_HEADER_LENGTH       (14)  #define isNull(ptr)        	(NULL == (ptr)) #define isNotNull(ptr)        (NULL != (ptr))  // BMP 文件头 typedef struct   {     //unsigned short    	bfType;  			// 2     unsigned long    	bfSize; 			// 4      unsigned short    	bfReserved1;       unsigned short    	bfReserved2;       unsigned long    	bfOffBits;   } ClBitMapFileHeader;  //BMP图片的信息头 typedef struct InfoHeader {  unsigned int 		bisize;				//信息头的大小,一般是40  int 				biWidth;			//位图的宽  int 				biHeight;			//位图的高  unsigned short 	biPlanes;			//固定值1  unsigned short 	biBitCount;			//每个像素的位数  unsigned int 		biCompression;		//压缩方式,BI_RGB(0)为不压缩, BI_BITFIELDS(3)用于16位、32位位图    unsigned int 		biSizeImage;		//位图全部像素占用的字节  int 				biXpelsPerMeter;	//水平分辨率  int 				biYPelsPerMeter;	//垂直分辨率  unsigned int 		biClrUsed;			//位图使用的颜色数。0代表颜色数为2的biBitCount次方  unsigned int 		biClrImportant;		//重要的颜色数,0代表所有颜色都重要   }BmpInfoHeader;  /* *函数功能:将bmp图片传入,输出BGR图像,图像方向是正的 *传参:	pSrcData(in)	——输入bmp图像数据 *		pDstData(out)	——输出BGR图像 *		pWidth(out)		——bmp图像的宽 *		pHeight	(out)	——bmp图像的高 * *返回值:成功返回0,失败返回-1 */ int BMPExtractBGR(char* pSrcData, char* pDstData, unsigned int *pWidth, unsigned int *pHeight) { 	 BmpInfoHeader BmpInfoHeader; 	 unsigned int width, height; 	 int i, j; 	 int offSet; 	 int RGB24 = 0; 	 unsigned short RGB16 = 0;   	 int count = 0; 	 ClBitMapFileHeader fHeader; 	  	 if(isNull(pSrcData) || isNull(pDstData)) 	 { 	  	printf("input parameter invalid\n"); 	  	return -1; 	 }  	//根据前两个字节,判断是不是BMP图片 	if ((pSrcData[0] != 'B') || (pSrcData[1] != 'M')) 	{ 		printf( "not a bmp picture.\n"); 		return -1; 	}  	//获取文件头,要跳过前两个字节 	memcpy(&fHeader, pSrcData + 2, sizeof(ClBitMapFileHeader)); 	 	 	//获取信息头 	memcpy(&BmpInfoHeader, pSrcData + BMP_FILE_HEADER_LENGTH, sizeof(BmpInfoHeader));   	width  = BmpInfoHeader.biWidth; 	height = BmpInfoHeader.biHeight;  	//将宽高信息传递出去 	*pWidth = width; 	*pHeight = height;  	printf("biBitCount = %d, bisize = %d, wxh=%dx%d, bfOffBits=%d, bfSize=%d\n", \ 				BmpInfoHeader.biBitCount, BmpInfoHeader.bisize, width, height, fHeader.bfOffBits, fHeader.bfSize);  	//判断BMP图片像素的位数 	if(BmpInfoHeader.biBitCount == BMP_24_BIT) 	{  		offSet = fHeader.bfOffBits;//文件头到BGR数据的偏移量 		 	j = 0; 	//读取文件的BRG数据 	for(i = height - 1; i >= 0; i-- ) 	{ 			memcpy(pDstData + j * width * 3, pSrcData + offSet + i * width * 3, width * 3); 			j++; 		} 	} 	else if(BmpInfoHeader.biBitCount == BMP_8_BIT) 	{  		offSet = BMP_FILE_HEADER_LENGTH + BmpInfoHeader.bisize + BMP_8_BIT_OFFSET; 		for(i = height - 1; i >= 0; i --) 		{ 		   	for(j = 0; j < width; j++) 		   	{  		    	memcpy(pDstData + count * 3, pSrcData + BMP_FILE_HEADER_LENGTH + BmpInfoHeader.bisize + 4 * (int)pSrcData[offSet + i * width + j], 3); 		    	count++; 		    } 		} 	} 	else if(BmpInfoHeader.biBitCount == BMP_16_BIT) 	{  	  	if(BmpInfoHeader.biCompression == BI_BITFIELDS) 	  	{  		   	//根据掩码判断是RGB555 		   	if((*((int *)(pSrcData + 54)) == RGB555_RED_MASK) && (*((int *)(pSrcData + 58)) == RGB555_GREEN_MASK) \ 		    	&& (*((int *)(pSrcData + 62)) == RGB555_BLUE_MASK)) 		   	{ 		    	//提取BGR数据 		    	for(i = height - 1; i >= 0; i--) 		    	{ 			     	for(j = 0; j < width; j++) 			     	{ 				      	RGB24 = 0; 				      	RGB16 = *((unsigned short *)(pSrcData + BMP_16_BIT_BI_BITFIELDS_OFFSET + 2 * (i * width + j))); 				      	RGB24 |= ((RGB16 & RGB555_RED_MASK) << 9) | ((RGB16 & RGB555_GREEN_MASK) << 6) | ((RGB16 & RGB555_BLUE_MASK) << 3); 				      	memcpy(pDstData + count * 3, &RGB24, 3); 				      	count++; 			     	} 		    	}    			} 	   		//根据掩码判断是RGB565 			else if((*((int *)(pSrcData + 54)) == RGB565_RED_MASK) && (*((int *)(pSrcData + 58)) == RGB565_GREEN_MASK) \ 			&& (*((int *)(pSrcData + 62)) == RGB565_BLUE_MASK)) 			{ 				for(i = height - 1; i >= 0; i--) 				{ 					 for(j = 0; j < width; j++) 					 { 					  	RGB24 = 0; 					  	RGB16 = *((unsigned short *)(pSrcData + BMP_16_BIT_BI_BITFIELDS_OFFSET + 2 * (i * width + j))); 					  	RGB24 |= ((RGB16 & RGB565_RED_MASK) << 8) | ((RGB16 & RGB565_GREEN_MASK) << 5) | ((RGB16 & RGB565_BLUE_MASK) << 3); 					  	memcpy(pDstData + count * 3, &RGB24, 3); 					  	count++; 					 } 				} 			}   		} 		else if(BmpInfoHeader.biCompression == BI_RGB) 		{ 			//提取BGR数据 			for(i = height - 1; i >= 0; i--) 			{ 				for(j = 0; j < width; j++) 				{ 					RGB24 = 0; 					RGB16 = *((unsigned short *)(pSrcData + BMP_16_BIT_BI_RGB_OFFSET + 2 * (i * width + j))); 					RGB24 |= ((RGB16 & RGB555_RED_MASK) << 9) | ((RGB16 & RGB555_GREEN_MASK) << 6) | ((RGB16 & RGB555_BLUE_MASK) << 3); 					memcpy(pDstData + count * 3, &RGB24, 3); 					count++; 				} 			} 		} 	} 	else if(BmpInfoHeader.biBitCount == BMP_32_BIT) 	{ 		offSet = BMP_FILE_HEADER_LENGTH + BmpInfoHeader.bisize;//文件头到BGR数据的偏移量 		count = 0; 		for(i = height - 1; i >= 0; i--) 		{ 			for(j = 0; j < width; j++) 			{ 				memcpy(pDstData + 3 *count, pSrcData + offSet + 4 *(i * width + j), 3); 				count++; 			}   		} 	} 	else 	{ 		printf("not support bmp format\n"); 		return -1; 	} 	  	return 0; }  

(1)BMPExtractBGR()函数功能是从BMP图像中提取出BGR数据,并将图像旋转180度,具体参数含义见注释;
(2)BMPExtractBGR()函数支持8bit、16bit、24bit、32bit的BMP图像格式;
(3)想要能直接编译成可执行程序的源码,可在我的资源里下载,该源码可直接将bmp格式转换成bgr格式
(3)需要完善的地方:上面的BMPExtractBGR()函数代码太多,可以将8bit、16bit、24bit、32bit的BMP格式分别拆分成单个函数,我不想花时间再调试,如果是要移植到公司的项目中,切记要拆分,不然函数代码这么长会被批斗的。

(1)在BMP的文件头中前两个字节是’BM’,是BMP图片的特征值,本来在文件头ClBitMapFileHeader结构体中应该用short变量去表示这两个字节,但实际在文件头结构体中将bfType变量注释掉,因为2个字节是没有对齐的,如果不注释掉则会因为结构体的变量对齐导致数据错位;
(2)文件头ClBitMapFileHeader结构体中使用了long型变量,long在32位机器中是4字节,在64位机器中是8字节,上面的代码只能在32位的机器上运行,在64位机器上运行会出错;

热门文章

10月17日更新21.5M/S,2024年最新高速Clash/V2ray/SSR/Shadowrocket订阅链接免费节点订阅

这一次的节点更新覆盖了日本、欧洲、加拿大、香港、韩国、美国、新加坡等地区,最高速度可达21.5 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

宠物领养合同有法律效应吗 宠物领养合同有法律效应吗知乎

摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于宠物领养合同有法律效应吗的问题,于是小编就整理了5个相关介绍宠物领养合同有法律效应吗的解答,让我们一起看看吧。签订领养宠物协议靠

11月25日更新19.6M/S,2024年最新高速Clash/V2ray/SSR/Shadowrocket订阅链接免费节点订阅

这一次的节点更新覆盖了韩国、美国、加拿大、香港、日本、新加坡、欧洲等地区,最高速度可达19.6 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

中国动物疫苗生产企业排名榜 中国动物疫苗生产企业排名榜最新

摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于中国动物疫苗生产企业排名榜的问题,于是小编就整理了2个相关介绍中国动物疫苗生产企业排名榜的解答,让我们一起看看吧。辉瑞和科兴是哪

C语言实现BMP格式转RGB格式、YUV格式

此代码的功能是传入BMP格式的数据,传出提取的RGB数据。BMP图像支持8bit、16bit、24bit、32bit的格式,得到的都是24bit的RGB格式图像,如果想得到YUV格式的图像,可以将得到

12月21日更新18.7M/S,2024年最新高速Shadowrocket/V2ray/SSR/Clash订阅链接免费节点地址分享

这一次的节点更新覆盖了加拿大、新加坡、香港、日本、韩国、欧洲、美国等地区,最高速度可达18.7 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

佳雯宠物医院环城西路店(佳雯宠物医院环城东路分院怎么样)

摘要: 今天给各位分享佳雯宠物医院环城西路店的知识,其中也会对佳雯宠物医院环城东路分院怎么样进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、佳雯宠.

12月14日更新18.5M/S,2024年最新高速Shadowrocket/Clash/SSR/V2ray订阅链接免费节点订阅

这一次的节点更新覆盖了欧洲、香港、韩国、日本、美国、加拿大、新加坡等地区,最高速度可达18.5 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

10月12日更新22.4M/S,2024年最新高速Shadowrocket/SSR/Clash/V2ray订阅链接免费节点订阅

这一次的节点更新覆盖了日本、欧洲、加拿大、美国、韩国、新加坡、香港等地区,最高速度可达22.4 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

12月19日更新20.6M/S,2024年最新高速Clash/V2ray/SSR/Shadowrocket订阅链接免费节点订阅

这一次的节点更新覆盖了香港、新加坡、加拿大、日本、美国、欧洲、韩国等地区,最高速度可达20.6 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

归纳