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