RGB888转RGB666
Posted maxiongying
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RGB888转RGB666相关的知识,希望对你有一定的参考价值。
内存中的数据排列高位在左,低位在右
RGB888->RGB666
高 -------低
B[3] B[2] B[1] B[0] B[3] B[2]
RGB888 RRRRRRRR GGGGGGGG BBBBBBB RRRRRRRR GGGGGGGG BBBBBBBB
A[2] A[1] A[0] A[2] A[1]
RGB666 RRRRRRGG GGGGBBBB BBRRRRRR GGGGGGBB BBBB
RGB888->RGB565
高-----------低
B[2] B[1] B[0]
RGB888 RRRRRRRR GGGGGGGG BBBBBBBB
A[1] A[0]
RGB565 RRRRRGGG GGGBBBBB
代码
#include "stdafx.h" #include <windows.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <list> using namespace std; #define WIDTHBYTES(bits) (((bits)+31)/32*4) typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef long LONG; //位图文件头信息结构定义 //其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息) typedef struct HS_tagBITMAPFILEHEADER{ WORD bfType;//固定为0x4d42 DWORD bfSize; //文件大小 WORD bfReserved1; //保留字,不考虑 WORD bfReserved2; //保留字,同上 DWORD bfOffBits;//实际位图数据的偏移字节数,即前三个部分长度之和 }HS_BITMAPFILEHEADER; //信息头BITMAPINFOHEADER,也是一个定义,其定义如下: typedef struct HS_tagBITMAPINFOHEADER{ DWORD biSize; //指定此结构体的长度,为40 LONG biWidth; //位图宽 LONG biHeight; //位图高 WORD biPlanes; //平面数,为1 WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32 DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩 DWORD biSizeImage; //实际位图数据占用的字节数 LONG biXPelsPerMeter; //X方向分辨率 LONG biYPelsPerMeter; //Y方向分辨率 DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数) DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的 }HS_BITMAPINFOHEADER; //调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。24位和32位是不需要调色板的。 //(似乎是调色板结构体个数等于使用的颜色数。) typedef struct HS_tagRGBQUAD { //public: BYTE rgbBlue; //该颜色的蓝色分量 BYTE rgbGreen; //该颜色的绿色分量 BYTE rgbRed; //该颜色的红色分量 BYTE rgbReserved; //保留值 } HS_RGBQUAD; void showBmpHead(HS_BITMAPFILEHEADER* pBmpHead) { printf("位图文件头:\n"); printf("bmp格式标志bftype:0x%x\n", pBmpHead->bfType); printf("文件大小:%d\n", pBmpHead->bfSize); printf("保留字1:%d\n", pBmpHead->bfReserved1); printf("保留字2:%d\n",pBmpHead->bfReserved2); printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits); } void showBmpInfoHead(HS_tagBITMAPINFOHEADER* pBmpInfoHead) { printf("位图信息头:\n"); printf("此结构体的长度:%d\n",pBmpInfoHead->biSize); printf("位图宽:%d\n",pBmpInfoHead->biWidth); printf("位图高:%d\n",pBmpInfoHead->biHeight); printf("biPlanes平面数:%d\n",pBmpInfoHead->biPlanes); printf("biBitCount采用颜色位数:%d\n",pBmpInfoHead->biBitCount); printf("压缩方式:%d\n",pBmpInfoHead->biCompression); printf("biSizeImage实际位图数据占用的字节数:%d\n",pBmpInfoHead->biSizeImage); printf("X方向分辨率:%d\n",pBmpInfoHead->biXPelsPerMeter); printf("Y方向分辨率:%d\n",pBmpInfoHead->biYPelsPerMeter); printf("使用的颜色数:%d\n",pBmpInfoHead->biClrUsed); printf("重要颜色数:%d\n",pBmpInfoHead->biClrImportant); } void showRgbQuan(HS_tagRGBQUAD* pRGB) { printf("(%-3d,%-3d,%-3d) ",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue); } FILE *fp_write; void writeRgb18Head(HS_tagBITMAPFILEHEADER* pBmpHead){ fwrite(&pBmpHead->bfType, 1, 2, fp_write); fwrite(&pBmpHead->bfSize, 1, 4, fp_write); fwrite(&pBmpHead->bfReserved1, 1, 2, fp_write); fwrite(&pBmpHead->bfReserved2, 1, 2, fp_write); fwrite(&pBmpHead->bfOffBits, 1, 4, fp_write); // fwrite(pBmpHead, 1, 14, fp_write); } void writeRgb18InfoHead(HS_tagBITMAPINFOHEADER* pBmpInfoHead) { fwrite(pBmpInfoHead, 1, 40, fp_write); } void rgb24_to_rgb565(BYTE* rgb24,BYTE* rgb16, int width, int height){ int i = 0; int j = 0; for(i = 0; i < width*height; i += 3) { rgb16[j] = ( rgb24[i] & 0xF1 ) >> 3; rgb16[j] |= ( rgb24[i+1] & 0x1C ) << 3; rgb16[j + 1] = rgb24[i+2] & 0xF8; rgb16[j + 1] |= (rgb24[i+1] & 0xF0) >> 5; j += 2; } } WORD rgb_24_2_565(int r, int g, int b) { return (WORD)(((unsigned(r) << 8) & 0xF800) | ((unsigned(g) << 3) & 0x7E0) | ((unsigned(b) >> 3))); } void rgb24_to_rgb666(BYTE* rgb24,BYTE* rgb18, int width, int height){ int i = 0; int j = 0; for(i = 0; i < width*height; i += 4) { rgb18[j] = rgb24[i] >> 2; rgb18[j] = rgb18[j] | ( ( rgb24[i+1] & 0x0C ) << 4 ); rgb18[j+1] = ( rgb24[i+1] & 0xF0 ) >> 4; rgb18[j+1] = rgb18[j+1] | ( ( rgb24[i+2] & 0x3C) << 2 ); rgb18[j+2] = ( rgb24[i+2] & 0xC0 ) >> 6; rgb18[j+2] = rgb18[j+2] | rgb24[i+3] & 0xFC; j += 3; } } int find_all_files(const char * lpPath, list<string> *picturePath) { char filePath[100] ; char szFind[MAX_PATH]; WIN32_FIND_DATA FindFileData; strcpy(szFind,lpPath); strcat(szFind,"\\*.*"); HANDLE hFind=::FindFirstFile(szFind,&FindFileData); if(INVALID_HANDLE_VALUE == hFind) return -1; do { if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(strcmp(FindFileData.cFileName,".")!=0 && strcmp(FindFileData.cFileName, "..")!=0) { //发现子目录,递归之 char szFile[MAX_PATH] = {0}; strcpy(szFile,lpPath); strcat(szFile,"\\"); strcat(szFile,FindFileData.cFileName); find_all_files(szFile, picturePath); } } else { //找到文件,处理之 string strPicturePath = lpPath; strPicturePath += "\\" ; strPicturePath += FindFileData.cFileName; picturePath->push_back(strPicturePath); } }while(::FindNextFile(hFind,&FindFileData)); ::FindClose(hFind); return 0; } void main() { HS_BITMAPFILEHEADER bitHead; HS_BITMAPINFOHEADER bitInfoHead; FILE* pfile; char filePath[50]; char *BmpFileHeader; WORD *temp_WORD; DWORD *temp_DWORD; string strPicturePath; string strPictureName; printf("please input the file path:\n"); scanf("%s",filePath); list<string> picturesPath; find_all_files(filePath, &picturesPath); BmpFileHeader=(char *)calloc(14,sizeof(char)); for(list<string>::iterator it = picturesPath.begin(); it != picturesPath.end(); ++it){ strPicturePath = *it; pfile = fopen(strPicturePath.c_str(),"rb");//打开文件 if(pfile!=NULL) { memset(BmpFileHeader, 0, 14); fread(BmpFileHeader,1,14,pfile); temp_WORD=(WORD* )(BmpFileHeader); bitHead.bfType=*temp_WORD; if(bitHead.bfType != 0x4d42) { printf("file is not .bmp file!"); continue; } temp_DWORD=(DWORD *)(BmpFileHeader+sizeof(bitHead.bfType)); bitHead.bfSize=*temp_DWORD; temp_WORD=(WORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)); bitHead.bfReserved1=*temp_WORD; temp_WORD=(WORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)+ sizeof(bitHead.bfReserved1)); bitHead.bfReserved2=*temp_WORD; temp_DWORD=(DWORD*)(BmpFileHeader+sizeof(bitHead.bfType)+sizeof(bitHead.bfSize)+sizeof(bitHead.bfReserved1)+sizeof(bitHead.bfReserved2)); bitHead.bfOffBits=*temp_DWORD; //showBmpHead(&bitHead); //printf("\n\n"); //写头文 int indexName = strPicturePath.find_last_of("\\"); strPictureName = strPicturePath.substr(indexName + 1); fp_write = fopen(strPictureName.c_str(), "wb"); //fp_write = fopen("NC_001_16.bmp", "wb"); //fp_write = fopen("NC_001_24.bmp", "wb"); //读取位图信息头信息 fread(&bitInfoHead,1,sizeof(HS_BITMAPINFOHEADER),pfile); bitHead.bfSize = WIDTHBYTES(bitInfoHead.biWidth*18) * bitInfoHead.biHeight + 54; //bitHead.bfSize = WIDTHBYTES(bitInfoHead.biWidth*16) * bitInfoHead.biHeight + 54; //bitHead.bfSize = WIDTHBYTES(bitInfoHead.biWidth*24) * bitInfoHead.biHeight + 54; writeRgb18Head(&bitHead); //showBmpInfoHead(&bitInfoHead); //printf("\n"); bitInfoHead.biBitCount = 18; //bitInfoHead.biBitCount = 16; //bitInfoHead.biBitCount = 24; bitInfoHead.biCompression = 0; bitInfoHead.biSizeImage = 0; bitInfoHead.biXPelsPerMeter = 0; bitInfoHead.biYPelsPerMeter = 0; bitInfoHead.biClrUsed = 0; bitInfoHead.biClrImportant = 0; writeRgb18InfoHead(&bitInfoHead); int width = bitInfoHead.biWidth; int height = bitInfoHead.biHeight; int l_width = WIDTHBYTES(width* 24);//计算位图的实际宽度并确保它为32的倍数 BYTE *pColorData=(BYTE *)malloc(height*l_width); memset(pColorData,0,height*l_width); long nData = height*l_width; //把位图数据信息读到数组里 fread(pColorData,1,nData,pfile); int width16 = WIDTHBYTES(width* bitInfoHead.biBitCount); BYTE* rgb16 = (BYTE*)malloc (width16* height); //rgb24_to_rgb565(pColorData,rgb16, l_width,height); rgb24_to_rgb666(pColorData,rgb16, l_width,height); fwrite(rgb16, 1, width16 * height, fp_write); fclose(pfile); fclose(fp_write); free(pColorData); free(rgb16); } else { printf("file open fail!\n"); } } free(BmpFileHeader); printf("successed!"); }
以上是关于RGB888转RGB666的主要内容,如果未能解决你的问题,请参考以下文章
ICN6202/ICN6202:MIPI转LVDS/mipi转RGB