24位深的bmp图片转换为16位深RGB565格式的bmp图片源码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Acoolbest/article/details/72406437
/**
    24位深的bmp图片转换为16位深RGB565格式的bmp图片
 **/
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

typedef unsigned char uint8;
typedef char int8;
typedef unsigned short  uint16; //32bit system
typedef short  int16;
typedef unsigned int uint32;//32bit system
typedef int int32;

struct bmp_filehead //14B
{
    //2B 'BM'=0x424d;   
    uint16 bmtype; //'BM',2B  
    uint32 bmSize; //size,4B  
    uint32 bmReserved;//0x00,4B
    uint32 bmOffBits;//4B,... 54

}head1;

struct bmphead //40B
{
    uint32 bmpOffBits;//4B,... 40
    uint32 bmp_wide;//4B,wide
    uint32 bmp_high;//4B,high 
    uint16 bmplans;//2B,0 or 1
    uint16 bitcount;//2B ,24
    uint32 bmpyasuo;//4B,0
    uint32 imagesize;//4B,w*h*3

    uint32 biXPelsPerMeter;
    uint32 biYPelsPerMeter;
    uint32 biClrUsed;
    uint32 biClrImportant;
}head2;

struct BGR_data //40B
{
    uint8 B_data;
    uint8 G_data;
    uint8 R_data;
}clr_data[1024*768]; //img size must less than 1024*768 

bool bmp565_write(unsigned char *image, uint32 width, uint32 height, const char *filename)      
{
    unsigned char buffer[1024*1024] = {0};
    uint32 file_size;     
    uint32 data_size;     
    unsigned int widthAlignBytes;     
    FILE *fp;     

    // 文件头     
    unsigned char header[66] = {     
        // BITMAPFILEINFO     
        'B', 'M',               // [0-1] bfType:必须是BM字符     
        0, 0, 0, 0,             // [2-5] bfSize:总文件大小      
        0, 0, 0, 0,             // [6-9] brReserved1,bfReserved2:保留     
        sizeof(header), 0, 0, 0,// [10-13] bfOffBits:到图像数据的偏移     
        // BITMAPFILEHEADER     
        0x28, 0, 0, 0,          // [14-17] biSize:BITMAPINFOHEADER大小40字节     
        0, 0, 0, 0,             // [18-21] biWidth:图片宽度     
        0, 0, 0, 0,             // [22-25] biHeight:图片高度     
        0x01, 0,                // [26-27] biPlanes:必须为1     
        0x10, 0,                // [28-29] biBitCount:16位     
        0x03, 0, 0, 0,          // [30-33] biCompression:BI_BITFIELDS=3     
        0, 0, 0, 0,             // [34-37] biSizeImage:图片大小     
        0x12, 0x0B, 0, 0,       // [38-41] biXPelsPerMeter:单位长度内的像素数     
        0x12, 0x0B, 0, 0,       // [42-45] biYPelsPerMeter:单位长度内的像素数     
        0, 0, 0, 0,             // [46-49] biClrUsed:可用像素数,设为0即可     
        0, 0, 0, 0,             // [50-53] biClrImportant:重要颜色数,设为0即可     
        // RGBQUAD MASK     
        0x0, 0xF8, 0, 0,        // [54-57] 红色掩码     
        0xE0, 0x07, 0, 0,       // [58-61] 绿色掩码     
        0x1F, 0, 0, 0           // [62-65] 蓝色掩码     
    };

    widthAlignBytes = ((width * 16 + 31) & ~31) / 8; // 每行需要的合适字节个数     
    data_size = widthAlignBytes * height;      // 图像数据大小     
    file_size = data_size + sizeof(header);    // 整个文件的大小

    printf("data_size:%d, widthAlignBytes:%d, width:%d, height:%d\n",data_size, widthAlignBytes, width, height);

    *((uint32*)(header + 2)) = file_size;     
    *((uint32*)(header + 18)) = width;     
    *((uint32*)(header + 22)) = height;     
    *((uint32*)(header + 34)) = data_size;     

    if (!(fp = fopen(filename, "wb")))     
        return false;     

    fwrite(header, sizeof(unsigned char), sizeof(header), fp);

    if (widthAlignBytes == width * 2)     
    {     
        fwrite(image, sizeof(unsigned char), (size_t)(data_size), fp);
    }     
    else     
    {
        // 每一行单独写入     
        const static int32 DWZERO = 0;     
        for (int i = 0; i < height; i++)     
        {     
            fwrite(image + i * width * 2, sizeof(unsigned char), (size_t) width * 2, fp);
            fwrite(&DWZERO, sizeof(unsigned char), widthAlignBytes - width * 2, fp);
        }
    }     

    fclose(fp);     
    return true;     
}
int main(int argc, char *argv[])
{
    unsigned char image_data[1024*1024] = {0};
    unsigned int image_index = 0;
    FILE *fp,*out_fp;
    int32 k,q;
    uint32 rec_cout,rec_cout2;
    uint16 tp_16bit;
    int8 src_file[64] = "";
    int8 dst_file[64] = "";

    if(argc < 2)
    {
        cout << "\nUsage:pls input src file path and dst file path\n" << endl;
        return -1;
    }
    printf("\n********************************************************\n"); 
    printf("*********24 bits bmp to 16 bits RGB565 bmp V1.0*********\n");
    printf("*********************zhzq 2017.5.17*********************\n");
    printf("********************************************************\n\n");
    strcpy(src_file, argv[1]);
    if(argc == 3)
    {
        strcpy(dst_file, argv[2]);
        cout << "dst file name : " << dst_file << endl;
    }
    else
    {
        strncpy(dst_file, src_file, strlen(src_file)-4);
        strcat(dst_file, "_rgb565.bmp");
        cout << "we set dst file default name : " << dst_file << endl;
    }


    if((fp=fopen(src_file,"r"))==NULL)
        cout<<"open error!"<<endl;
    else
    {
        fseek(fp, 0, 0);//fseek(fp, offset, fromwhere);
        rec_cout=fread(&head1,sizeof(head1),1,fp);

        fseek(fp, 14, 0);//fseek(fp, offset, fromwhere);
        rec_cout2=fread(&head2,sizeof(head2),1,fp);

        fseek(fp, 54, 0);//fseek(fp, offset, fromwhere);
        rec_cout2=fread(&clr_data,3,(head2.bmp_wide*head2.bmp_high),fp);

        fclose(fp);

        cout<<"open ok!"<<endl;
        if(rec_cout>=0)
        {
            cout<<"write bmp 565 start !"<<endl;
            for(k=0;k<head2.bmp_high;k++)
                for(q=0;q<head2.bmp_wide;q++)
                {
                    tp_16bit=((uint16)(clr_data[k*head2.bmp_wide+q].R_data>>3)<<11)//R G B
                        +((uint16)(clr_data[k*head2.bmp_wide+q].G_data>>2)<<5)
                        +(uint16)(clr_data[k*head2.bmp_wide+q].B_data>>3);
                    image_data[image_index++] = uint8(tp_16bit&0xff);
                    image_data[image_index++] = uint8(tp_16bit>>8);
                }
            if(bmp565_write(image_data, head2.bmp_wide, head2.bmp_high, dst_file))
                cout<<"write bmp 565 success !"<<endl;
            else
                cout<<"write bmp 565 failed !"<<endl;

            #if 0
            cout<<"rt="<<rec_cout<<endl<<endl;

            printf("typ=0x%04X \n",head1.bmtype);
            printf("bmSize=0x%08X \n",head1.bmSize);
            printf("bmReserved=0x%08X \n",head1.bmReserved);
            printf("bmOffBits=0x%08X \n\n",head1.bmOffBits);


            printf("bmpOffBits=0x%08X \n",head2.bmpOffBits);
            printf("bmp_wide=0x%08X \n",head2.bmp_wide);
            printf("bmp_high=0x%08X \n",head2.bmp_high);
            printf("bitcount=0x%08X \n",head2.bitcount);
            printf("imagesize=0x%08X \n",head2.imagesize);

            for(k=(0+head2.bmp_wide*(head2.bmp_high/2));
                    k<(100+head2.bmp_wide*(head2.bmp_high/2));k++)
            {
                printf("BGR=0x%02X,0x%02X,0x%02X \n",clr_data[k].B_data,
                        clr_data[k].G_data,clr_data[k].R_data);
            }

            if((out_fp=fopen("Imag.C","w+"))==NULL)
            {
                printf("can't open\n");
            }
            else
            {
                printf("Open success!!\n");
                //fseek(out_fp, 0, 0);//fseek(fp, offset, fromwhere);
                //rec_cout=fwrite(&clr_data,100,1,out_fp);
                fprintf(out_fp,"const unsigned char gImage_Imag[%d] = { ",
                        head2.bmp_wide*head2.bmp_high*2+8);

                fprintf(out_fp,
                        "0X00,0X10,0X%02X,0X%02X,0X%02X,0X%02X,0X01,0X1B,\n",
                        /*scan,gray,wL,wH,hL,hH,is565,rgb*/
                        head2.bmp_wide&0xff,head2.bmp_wide>>8,
                        head2.bmp_high&0xff,head2.bmp_high>>8);

                //for(k=0;k<head2.bmp_wide*head2.bmp_high;k++)
                for(k=(head2.bmp_high-1);k>=0;k--)
                    for(q=0;q<head2.bmp_wide;q++)
                    {
                        tp_16bit=((uint16)(clr_data[k*head2.bmp_wide+q].R_data>>3)<<11)//R G B
                            +((uint16)(clr_data[k*head2.bmp_wide+q].G_data>>2)<<5)
                            +(uint16)(clr_data[k*head2.bmp_wide+q].B_data>>3);

                        fprintf(out_fp, "0X%02X,0X%02X,",(tp_16bit&0xff),(tp_16bit>>8)); //L H

                        if((q+1)%8==0)
                            fprintf(out_fp, "\r\n");
                    }
                fprintf(out_fp, "};\n");
                fclose(fp);
            }
            #endif
        }
        else
            cout<<"read error"<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Acoolbest/article/details/72406437
今日推荐