python rgb565_RGB565的转换

news/2025/3/17 20:55:32/

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;

}


http://www.ppmy.cn/news/542120.html

相关文章

图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别

音视频实践学习 android全平台编译ffmpeg以及x264与fdk-aac实践ubuntu下使用nginx和nginx-rtmp-module配置直播推流服务器android全平台编译ffmpeg合并为单个库实践android-studio使用cmake编译ffmpeg实践android全平台编译ffmpeg视频解码器实践android全平台编译ffmpeg支持命…

16位Alpha颜色混合(565)

手机上的一些小图标&#xff0c;当按下这些图标时&#xff0c;颜色会发生改变&#xff0c;实现的方式是怎么样的&#xff1f;先看一篇网络上流传的文章&#xff1a; //----------------------------------------------------------------------------------------------------…

Codeforces Round #565 (Div. 3)

div3题目一般都是思维题&#xff0c;算法比较少&#xff0c;用来训练思维和解题速度很合适 A题 模拟即可 #include <iostream> using namespace std; typedef long long ll; int main(){int q;ll n;cin >> q;while(q--){cin >> n;int ans 0;while(n ! 1)…

CH565 DVP sensor选型、性能评估

-----------------------转载注明出处 在使用CH565芯片的DVP接口的时候&#xff0c;涉及到摄像头选型的时候还是有一些困惑的&#xff0c;主要就是具体某个分辨率帧率能不能传输。 首先DVP接口是一个并行接口&#xff0c;存在4线、8线、12线的可配置传输宽度。同时96MHz的时钟…

5.2.2如何改变文件属性与权限

常用于群组、拥有者、各种身份的权限之修改的指令&#xff0c;如下所示&#xff1a; 改变一个文件的群组很简单&#xff0c;直接chgrp来改变&#xff0c;指令就是change group。要被改变的群组名称必须要在/etc/group文件内存在才行&#xff0c;否则就会显示错误。 假设你已经…

工地扬尘智能监测系统 yolov7

工地扬尘智能监测系统通过yolov7网络算法模型技术&#xff0c;实时监测工地施工中的扬尘情况。工地扬尘智能监测系统利用AI视频智能分析技术&#xff0c;并将数据传输到数据中心进行分析。YOLOv7 的发展方向与当前主流的实时目标检测器不同&#xff0c;研究团队希望它能够同时支…

【T+】安装畅捷通T+提示安装向导找不到环境检测工具,是否手动选择环境检测工具文件夹。

【问题描述】 在windows server 2008r2系统环境下&#xff0c; 安装畅捷通T专属云标准版18.0软件的时候&#xff0c;提示&#xff1a; 安装向导找不到环境检测工具&#xff0c;是否手动选择环境检测工具文件夹&#xff08;CheckEnvironment&#xff09; 点击【是】手动选择&…

基于STM32的矩阵电子密码锁的Proteus仿真

本设计仅供参考 基于STM32的矩阵电子密码锁的Proteus仿真 (源码仿真原理图PCB) 原理图&#xff1a;Altium Designer 仿真图&#xff1a;protues 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 编号C0034 【腾讯文档】C0034 网盘链接 资料下载链接 主要功能&…