zoukankan      html  css  js  c++  java
  • 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("位图文件头:
    ");
        printf("bmp格式标志bftype:0x%x
    ", pBmpHead->bfType);
        printf("文件大小:%d
    ", pBmpHead->bfSize);
        printf("保留字1:%d
    ", pBmpHead->bfReserved1);
        printf("保留字2:%d
    ",pBmpHead->bfReserved2);
        printf("实际位图数据的偏移字节数:%d
    ",pBmpHead->bfOffBits);
    }
    
    void showBmpInfoHead(HS_tagBITMAPINFOHEADER* pBmpInfoHead)
    {
        printf("位图信息头:
    ");
        printf("此结构体的长度:%d
    ",pBmpInfoHead->biSize);
        printf("位图宽:%d
    ",pBmpInfoHead->biWidth);
        printf("位图高:%d
    ",pBmpInfoHead->biHeight);
        printf("biPlanes平面数:%d
    ",pBmpInfoHead->biPlanes);
        printf("biBitCount采用颜色位数:%d
    ",pBmpInfoHead->biBitCount);
        printf("压缩方式:%d
    ",pBmpInfoHead->biCompression);
        printf("biSizeImage实际位图数据占用的字节数:%d
    ",pBmpInfoHead->biSizeImage);
        printf("X方向分辨率:%d
    ",pBmpInfoHead->biXPelsPerMeter);
        printf("Y方向分辨率:%d
    ",pBmpInfoHead->biYPelsPerMeter);
        printf("使用的颜色数:%d
    ",pBmpInfoHead->biClrUsed);
        printf("重要颜色数:%d
    ",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:
    ");
        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("
    
    ");
    
                //写头文
                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("
    ");
                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!
    ");
            }
        }
    
        free(BmpFileHeader);
    
        printf("successed!");
    }
  • 相关阅读:
    强化学习——Q-learning算法
    嵌入(embedding)层的理解
    福昕PDF电子文档处理套装软件中文企业版9.01
    奇异值分解(SVD)原理与在降维中的应用
    C++ Primer 笔记——迭代器
    Windows Internals 笔记——线程局部存储区
    C/C++中二进制与文本方式打开文件的区别
    C++ Primer 笔记——固有的不可移植的特性
    C++ Primer 笔记——union
    C++ Primer 笔记——嵌套类 局部类
  • 原文地址:https://www.cnblogs.com/senior-engineer/p/5584144.html
Copyright © 2011-2022 走看看