欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

bmp的24bit位宽转16bit

程序员文章站 2022-07-01 21:48:44
...

转载来自:

https://blog.csdn.net/youyoufengxinzi/article/details/1516523

#include <stdio.h
#include <stdlib.h>
#include <string.h>

#define BMP_TYPE 0x424D
#define BI_RGB               0
#define BMP1555_BYTE       2
#define BMP24_BYTE     3
#define BMP32_BYTE 4
#define CURBMP_BYTE            BMP24_BYTE
#define BMP24_TO_16(B, G, R)   ((B << 0)|(G << 5)|(R << 10))

typedef unsigned short WORD;
typedef unsigned int  DWORD;
typedef unsigned int  LONG;

#pragma pack(1)
typedef struct tagBITMAPFILEHEADER {
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER; //7

#pragma pack(1)
typedef struct tagBITMAPINFOHEADER {
    DWORD  biSize;
    LONG   biWidth;
    LONG   biHeight;
    WORD   biPlanes;
    WORD   biBitCount;
    DWORD  biCompression;
    DWORD  biSizeImage;
    LONG   biXPelsPerMeter;
    LONG   biYPelsPerMeter;
    DWORD  biClrUsed;
    DWORD  biClrImportant;
} BITMAPINFOHEADER; //56

int main(int argc,char** argv) {
    int nErrorCode=0;
    FILE *fin;
    FILE *fout;
    char szInFilename[256];
    char szOutFilename[256];
    printf("short:%d, int:%d, long:%d. data:%d\n", sizeof(short), sizeof(int), sizeof(long), sizeof(BITMAPINFOHEADER));
    if(argc==3) {
        strcpy(szInFilename ,argv[1]);
        strcpy(szOutFilename,argv[2]);
    } else {
        printf("invalid param.\n");
        return 0;
        strcpy(szInFilename , "333.bmp");
        strcpy(szOutFilename, "444.bmp");
    }

    printf("src:%s, dest:%s\n",szInFilename,szOutFilename);
    fin  = fopen(szInFilename , "rb");
    fout = fopen(szOutFilename, "wb");

    if(fin && fout)  {
        //get BufHeader
        BITMAPFILEHEADER BmpBufHeader;
        if(fread(&BmpBufHeader, 1, sizeof(BITMAPFILEHEADER), fin))  {
            printf("Type:  0x%x\n",BmpBufHeader.bfType);
            printf("Size:  0x%x\n",BmpBufHeader.bfSize);
            printf("Offset:%d\n"  ,BmpBufHeader.bfOffBits);
        } else {
            nErrorCode |= 0x2;
        }

        //get InfoHeader
        BITMAPINFOHEADER BmpInfoHeader;
        if(fread(&BmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fin))  {
            printf("biWidth :   %d\n",BmpInfoHeader.biWidth);
            printf("biHeight:   %d\n",BmpInfoHeader.biHeight);
            printf("biBitCount: %d\n",BmpInfoHeader.biBitCount);
        } else {
            nErrorCode |= 0x4;
        }

        //handle Header
        int BmpDataNum;
        if(BmpInfoHeader.biBitCount != BMP24_BYTE*8 && BmpBufHeader.bfType != BMP_TYPE && BmpInfoHeader.biCompression != BI_RGB) {
            nErrorCode |= 0x8;
        }
        BmpInfoHeader.biBitCount  = BMP1555_BYTE * 8;
        BmpDataNum = (BmpBufHeader.bfSize - BmpBufHeader.bfOffBits) / CURBMP_BYTE;
        BmpBufHeader.bfSize = BmpDataNum * BMP1555_BYTE * 8 + BmpBufHeader.bfOffBits;
        BmpInfoHeader.biSizeImage = (BmpInfoHeader.biSizeImage * BMP1555_BYTE) / CURBMP_BYTE;

        //get BmpData
        fseek(fin, 54, SEEK_SET);
        unsigned char  *BmpDatabuff    = (unsigned char  *)malloc(CURBMP_BYTE   * BmpDataNum);
        unsigned short *BmpDatabuffNew = (unsigned short  *)malloc(BMP1555_BYTE * BmpDataNum);
        if(!fread (BmpDatabuff, 1, CURBMP_BYTE * BmpDataNum, fin))
            nErrorCode |= 0x10;
        memset(BmpDatabuffNew, 0, BMP1555_BYTE * BmpDataNum );

        //handle BmpData(important)
        int i;
        unsigned int B,G,R;
        for(i = 0; i < BmpDataNum; i++) {
            B = (BmpDatabuff[i*CURBMP_BYTE+0] >> 3)&0x1F;//blue
            G = (BmpDatabuff[i*CURBMP_BYTE+1] >> 3)&0x1F;//green
            R = (BmpDatabuff[i*CURBMP_BYTE+2] >> 3)&0x1F;//red
            BmpDatabuffNew[i] = (unsigned short)BMP24_TO_16(B, G, R);
        }

        //creat NewBmp
        fseek(fout, 0, SEEK_SET);
        if(!fwrite(&BmpBufHeader , 1, sizeof(BITMAPFILEHEADER), fout))  {
            nErrorCode |= 0x20;
        }
        if(!fwrite(&BmpInfoHeader, 1, sizeof(BITMAPINFOHEADER), fout))  {
            nErrorCode |= 0x40;
        }
        fseek(fout, 54, SEEK_SET);
        if(!fwrite(BmpDatabuffNew, BMP1555_BYTE, BmpDataNum, fout)) {
            nErrorCode |= 0x80;
        }

    } else{
        nErrorCode |= 0x1;
    }

    if(fin) {
        fclose(fin);
    }
    if(fout) {
        fclose(fout);
    }
    printf("nErrorCode: %d\n", nErrorCode);
    printf("BMP32_TO_16:%s\n",!nErrorCode?"success":"fail");
    return nErrorCode;
}

相关标签: Linux c语言