BMP RGB888 To BMP RGB565\RGB555

                       BMP RGB888 To BMP RGB565\RGB555

#include"BMP.h"

#define RGB16_BITCOUNT 16
#define RGB24_BITCOUNT 24

#define RGB565_R 0xf8
#define RGB565_G 0xfc
#define RGB565_B 0xf8
T_U8* RGB24BitTRGB16Bit(T_U8 *src_img,BMP_TYPE bmp_type, DWORD width,DWORD height)
{
	T_U8 *bmp,*dst,*src_dst;
	WORD *temp,K;
	T_U32 B,G,R,g1,b1,r1,dst_line_byte,src_line_byte, i=0, j=0;
	BITMAPFILEHEADER bf;
	BITMAPINFOHEADER bi;
	RGBQUAD pcolorTable[3]={0}; 
	dst_line_byte = WIDTHBYTES(width*RGB16_BITCOUNT);
	src_line_byte = WIDTHBYTES(width*RGB24_BITCOUNT);

	

	switch(bmp_type)
	{
	case RGB565: //用Windows图片查看软件显示的是32bit位深,这个是Windows显示的问题 PS显示图像可见  但是偏红2019.9.27
		{
		
			pcolorTable[0].rgbBlue	= 0x00;
			pcolorTable[0].rgbGreen = 0xF8;
			pcolorTable[0].rgbRed	= 0x00;
			pcolorTable[0].rgbReserved	= 0x00;

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

			pcolorTable[2].rgbBlue	= 0x1F;
			pcolorTable[2].rgbGreen = 0x00;
			pcolorTable[2].rgbRed	= 0x00;
			pcolorTable[2].rgbReserved	= 0x00;
			
			memset(&bf, 0, sizeof(bf));
			memset(&bi, 0, sizeof(bi));

			bf.bfType = 0x4d42;
			bf.bfSize = 54 +3*sizeof(RGBQUAD)+ height*dst_line_byte;
			bf.bfOffBits = 54+3*sizeof(RGBQUAD);

			bi.biSize = 40;
			bi.biWidth = width;
			bi.biHeight = height;
			bi.biPlanes = 1;
			bi.biBitCount = 16;
			bi.biCompression = BI_BITFIELDS;
			bi.biXPelsPerMeter = 0;
			bi.biYPelsPerMeter = 0;
			bi.biClrImportant = 0;
			bi.biClrUsed = 0;
			bi.biSizeImage = height*dst_line_byte;

			
			bmp = (T_U8*)malloc(54+3*sizeof(RGBQUAD)+height*dst_line_byte);
			if (!bmp)
			{
				return 0;
			}
			memset(bmp, 0, bf.bfSize);
			memcpy(bmp, &bf, 14);
			memcpy(&bmp[14], &bi, 40);
			memcpy(&bmp[54],pcolorTable,3*sizeof(RGBQUAD));

			src_dst = src_img+54;
			dst		= bmp+54+3*sizeof(RGBQUAD);

			for(i = 0;i < height;i++)
			{

				temp = (WORD *)(dst+dst_line_byte*i);
				for(j = 0;j < width;j++)
				{
					B = src_dst[i*src_line_byte+j*3+0];
					G = src_dst[i*src_line_byte+j*3+1];
					R = src_dst[i*src_line_byte+j*3+2];

					/* Method 1  做了四舍五入,图像效果比没有做四舍五入效果稍好
					R = ((R)+4)>>3;
					G = ((G)+2)>>2;
					B = ((B)+4)>>3;

					if(R > 31) R = 31;
					if(G > 63) G = 63;
					if(B > 31) B = 31;

					//K = ((R << 11)|(G << 5)|(B<<0)); //内存中的保存形式 B分量在低地址
					*temp++ = ((R << 11)|(G << 5)|(B));
					*/
					*temp++ = ((R<<8)&0xF800)|(((G)<<3)&0x7e0)|((B)>>3);
				}
			}
			
		}
		break;
	
	
	case RGB555:
		{
			memset(&bf, 0, sizeof(bf));
			memset(&bi, 0, sizeof(bi));

			bf.bfType = 0x4d42;
			bf.bfSize = 54 + height*dst_line_byte;
			bf.bfOffBits = 54;

			bi.biSize = 40;
			bi.biWidth = width;
			bi.biHeight = height;
			bi.biPlanes = 1;
			bi.biBitCount = 16;
			bi.biCompression = BI_RGB;
			bi.biXPelsPerMeter = 0;
			bi.biYPelsPerMeter = 0;
			bi.biClrImportant = 0;
			bi.biClrUsed = 0;
			bi.biSizeImage = height*dst_line_byte;


			bmp = (T_U8*)malloc(54+height*dst_line_byte);
			if (!bmp)
			{
				return 0;
			}
			memset(bmp, 0, bf.bfSize);

			memcpy(bmp, &bf, 14);
			memcpy(&bmp[14], &bi, 40);
			
			src_dst = src_img+54;
			dst		= bmp+54;
			for(i = 0;i < height;i++)
			{
				temp = (WORD *)(dst+dst_line_byte*i);
				for(j = 0;j < width;j++)
				{

					B = src_dst[i*src_line_byte+j*3+0];
					G = src_dst[i*src_line_byte+j*3+1];
					R = src_dst[i*src_line_byte+j*3+2];

					// Method 1  做了四舍五入,图像效果比没有做四舍五入效果稍好
					R = ((R)+4)>>3;
					G = ((G)+4)>>3;
					B = ((B)+4)>>3;

					if(R > 31) R = 31;
					if(G > 31) G = 31;
					if(B > 31) B = 31;
					*temp++ = ((R << 10)|(G << 5)|(B)); //注意最高位保留,总为0
					//////method1//////////////////////////////////////////////////

					//*temp++ = (((R<<7)&0x7c00)|((G<<2)&0x3e0)|(B>>3)); //method 2
					//*temp++ = (((R>>3) << 10)|((G>>3) << 5)|(B>>3));	// method 3

				}			
			}
		}
		break;
	default:
		break;
	}

	return bmp;
}






整体图像,左到右分别是RGB888、RGB565、RGB555
右下角放大图像,左到右分别是RGB888、RGB565、RGB555
整体图像,左到右分别是RGB888、RGB555、RGB565
右上角放大图像,左到右分别是RGB888、RGB555、RGB565

图像比较小的时候基本上看不出来差别,放大看才能看到RGB555的天空分层比RGB565严重些,因为损失的图像数据更多些。

发布了49 篇原创文章 · 获赞 138 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/lz0499/article/details/103153055