python rgb565_RGB565的转换

24bit RGB888 -> 16bit RGB565 的转换

24ibt RGB888 {R7 R6 R5 R4 R3 R2 R1 R0} {G7 G6 G5 G4 G3 G2 G1 G0} {B7 B6 B5 B4 B3 B2 B1 B0}

16bit RGB656 {R7 R6 R5 R4 R3} {G7 G6 G5 G4 G3 G2} {B7 B6 B5 B4 B3}

可以修正,比如(当然人眼无法感觉,但是RG888-RGB565-RGB888的时候更好补偿)

R:197=>197>>3=24

R:197=192+5=>24+0.625≈25

所以

R5=R[2] ? R[7:3]+1 : R[7:3];

G5=G[1] ? G[7:2]+1 : G[7:2];

B5=B[2] ? B[7:3]+1 : B[7:3];

16bit RGB565 -> 24bit RGB888 的转换

16bit RGB656 {R4 R3 R2 R1 R0} {G5 G4 G3 G2 G1 G0} {B4 B3 B2 B1 B0}

24ibt RGB888 {R4 R3 R2 R1 R00 0 0} {G5 G4 G3 G2 G1 G0 0 0} {B4 B3 B2 B1 B0 0 0 0}

进行精度补偿(剩余的用低位进行补偿)

24ibt RGB888 {R4 R3 R2 R1 R0 R2 R1 R0} {G5 G4 G3 G2 G1 G0 G1 G0} {B4 B3 B2 B1 B0 B2 B1 B0}

总结一下:

1、量化压缩的方法:

三个字节对应取高位

2、量化补偿的方法:

(1) 将原数据填充至高位

(2) 对于低位,用原始数据的低位进行补偿

3、RGB565互转代码

#define RGB565_MASK_RED 0xF800

#define RGB565_MASK_GREEN 0x07E0

#define RGB565_MASK_BLUE 0x001F

void rgb565_2_rgb24(BYTE *rgb24, WORD rgb565) //分离出单独的RGB

{

rgb24[2] = (rgb565 & RGB565_MASK_RED) >> 11;

rgb24[1] = (rgb565 & RGB565_MASK_GREEN) >> 5;

rgb24[0] = (rgb565 & RGB565_MASK_BLUE);

//往高位移动填满单字节的8位

rgb24[2] <<= 3;

rgb24[1] <<= 2;

rgb24[0] <<= 3;

}

下面的代码来自这个网址:

#ifndef WIDTHBYTES#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8)

#endif

//BITMAPINFOHEADER m_bmih;//BYTE *m_pR;//BYTE *m_pG;//BYTE *m_pB;

BOOL CImageProcessor::LoadFileFromBitmap(LPCTSTR lpFileName)

{if(lpFileName ==NULL)

{returnFALSE;

}

HANDLE hFile= ::CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);if(hFile ==INVALID_HANDLE_VALUE)

{returnFALSE;

}

BOOL bRet=FALSE;do{

LARGE_INTEGER liSize;

liSize.QuadPart= 0;

::GetFileSizeEx(hFile,&liSize);

BITMAPFILEHEADER bmfh;

BITMAPINFOHEADER bmih;

DWORD dwByteRead= 0;

::ReadFile(hFile,&bmfh, sizeof(bmfh), &dwByteRead, NULL);if(dwByteRead < sizeof(bmfh))

{break;

}if(bmfh.bfType != 'MB' || bmfh.bfSize > liSize.QuadPart || bmfh.bfOffBits >liSize.QuadPart)

{break;

}

dwByteRead= 0;

::ReadFile(hFile,&bmih, sizeof(bmih), &dwByteRead, NULL);if(dwByteRead < sizeof(bmih))

{break;

}int nBitmapSize = abs(bmih.biHeight) * WIDTHBYTES(bmih.biWidth *bmih.biBitCount);if(bmih.biPlanes != 1)

{break;

}if(bmih.biBitCount != 1 && bmih.biBitCount != 4 && bmih.biBitCount != 8 && bmih.biBitCount != 16 && bmih.biBitCount != 24 && bmih.biBitCount != 32)

{break;

}if(bmih.biCompression != BI_RGB && bmih.biCompression !=BI_BITFIELDS)

{break;

}if(bmih.biWidth <= 0 || bmih.biHeight == 0)

{break;

}if(bmfh.bfOffBits + nBitmapSize >liSize.QuadPart)

{break;

}

m_pR= new BYTE[bmih.biWidth *abs(bmih.biHeight)];

m_pG= new BYTE[bmih.biWidth *abs(bmih.biHeight)];

m_pB= new BYTE[bmih.biWidth *abs(bmih.biHeight)];if(bmih.biBitCount < 16)

{//...

}else if(bmih.biBitCount == 16)

{//...

}else if(bmih.biBitCount == 24)

{

::SetFilePointer(hFile, bmfh.bfOffBits, NULL, SEEK_SET);

BYTE*pData = newBYTE[nBitmapSize];

dwByteRead= 0;

::ReadFile(hFile, pData, nBitmapSize,&dwByteRead, NULL);

BYTE*pR =m_pR;

BYTE*pG =m_pG;

BYTE*pB =m_pB;for(int j = 0; j < abs(bmih.biHeight); j++)

{

BYTE*pTemp = pData + WIDTHBYTES(bmih.biWidth * bmih.biBitCount) *j;for(int i = 0; i < bmih.biWidth; i++)

{*pB++ = *pTemp++;*pG++ = *pTemp++;*pR++ = *pTemp++;

}

}

delete[] pData;

}else if(bmih.biBitCount == 32)

{//...

}

memcpy(&m_bmih, &bmih, sizeof(m_bmih));

bRet=TRUE;

}while(0);

CloseHandle(hFile);returnbRet;

}

BOOL CImageProcessor::SaveFile565(HANDLE hFile)

{

BITMAPFILEHEADER bmfh;

BITMAPINFOHEADER bmih;

memset(&bmfh, 0, sizeof(bmfh));

memset(&bmih, 0, sizeof(bmih));int nBitmapSize = abs(m_bmih.biHeight) * WIDTHBYTES(m_bmih.biWidth * 16);

bmfh.bfType= 'MB';

bmfh.bfOffBits= sizeof(bmfh) + sizeof(bmih) + 12;

bmfh.bfSize= bmfh.bfOffBits +nBitmapSize;

bmih.biSize= sizeof(bmih);

bmih.biWidth=m_bmih.biWidth;

bmih.biHeight=m_bmih.biHeight;

bmih.biPlanes= 1;

bmih.biBitCount= 16;

bmih.biCompression=BI_BITFIELDS;

bmih.biSizeImage=nBitmapSize;

BYTE*pData = newBYTE[nBitmapSize];

memset(pData,0, nBitmapSize);

BYTE*pR =m_pR;

BYTE*pG =m_pG;

BYTE*pB =m_pB;for(int j = 0; j < abs(bmih.biHeight); j++)

{

WORD*pTemp = (WORD *)(pData + WIDTHBYTES(bmih.biWidth * 16) *j);for(int i = 0; i < bmih.biWidth; i++)

{#if 1

*pTemp++ = ((WORD)(*pR++ << 8) & 0xf800) | ((WORD)(*pG++ << 3) & 0x07e0) | ((WORD)(*pB++ >> 3) & 0x001f);#else

int nR = (*pR++ + 4) >> 3;int nG = (*pG++ + 2) >> 2;int nB = (*pB++ + 4) >> 3;if(nR > 31) nR = 31;if(nG > 63) nG = 63;if(nB > 31) nB = 31;*pTemp++ = (nR << 11) | (nG << 5) |nB;#endif}

}

DWORD nRGBMask[3];

nRGBMask[0] = 0xf800;

nRGBMask[1] = 0x07e0;

nRGBMask[2] = 0x001f;

DWORD dwByteWritten= 0;

::WriteFile(hFile,&bmfh, sizeof(bmfh), &dwByteWritten, NULL);

::WriteFile(hFile,&bmih, sizeof(bmih), &dwByteWritten, NULL);

::WriteFile(hFile, nRGBMask,sizeof(nRGBMask), &dwByteWritten, NULL);

::WriteFile(hFile, pData, nBitmapSize,&dwByteWritten, NULL);

delete[] pData;returnTRUE;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值