BMP 文件到 PNG 文件转换器

Posted

技术标签:

【中文标题】BMP 文件到 PNG 文件转换器【英文标题】:BMP File to PNG File Converter 【发布时间】:2020-04-04 17:35:13 【问题描述】:

我正在制作 BMP 到 PNG 转换器。 BMP 图像未压缩。

所以我的问题是当 BMP 文件转换为 PNG 文件时,PNG 文件是否被压缩,即图像数据是否被压缩。如果是这样,图像数据如何以 PNG 文件格式对齐?

如果PNG图像数据未压缩,那么BMP图像数据如何在PNG文件中对齐。

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

#pragma pack(1)
typedef struct

        unsigned short int  st_m40_FileType;

        unsigned int        st_m40_ImgFileSize;

        unsigned short int  st_m40_RsvdBytes1;

        unsigned short int  st_m40_RsvdBytes2;

        unsigned int        st_m40_ImgDataOffset;

        unsigned int        st_m40_Info40HeaderSze;

        int         st_m40_PxWdth;

        int         st_m40_PxHeight;

        unsigned short int  st_m40_NumOfColrPlnes;

        unsigned short int  st_m40_BitsPerPixel;

        unsigned int        st_m40_CmprsnType;

        unsigned int        st_m40_AftrCmprsnImgDataSze;

        int         st_m40_xResolutn_ppm;

        int         st_m40_yResolutn_ppm;

        unsigned int        st_m40_NumOfColrTbleColrs;

        unsigned int        st_m40_NumOfImprtntColrs;

ST_BMP40HEADER_t;

typedef struct 


        ST_BMP40HEADER_t    st_mBMP40MainHdrVar;

        unsigned char *     pst_mImgeData;

ST_IMAGE_40_HEADER_t;


typedef enum

        BI_RGB = 0x00,
        BI_RLE8,
        BI_RLE4,
        BI_BITFIELDS,
        BI_JPEG,
        BI_PNG,
        BI_ALPHABITFIELDS,
        BI_CMYK,
        BI_CMYKRLE8,
        BI_CMYKRLE4,

EN_BMP_COMPRESN_TYPE_t;

#pragma pack(1)
typedef struct 

        int         st_mImgWdth;
        int         st_ImgHeight;
        unsigned char   st_mBitDepth;
        unsigned char   st_mColorType;
        unsigned char   st_mCmprsnMthd;
        unsigned char   st_mFltrMthd;
        unsigned char   st_mInterlaceMthd;

ST_IHDR_DATA_FIELDS_t;

#pragma pack(1)
typedef struct 

        unsigned int    st_mChunkDataLngth;
        unsigned char   st_mChunkType[4];
        ST_IHDR_DATA_FIELDS_t       st_IHDR_DataFieldsVar;
        unsigned int    st_mCRC32CheckSum;

ST_IHDR_t;

#pragma pack(1)
typedef struct

        unsigned int        st_mPLTE_ChunkDataLngth;
        unsigned char       st_mPLTE_ChunkType[4];
        unsigned char*      st_mPLTE_ChunkDataPtr;
        unsigned int        st_mPLTE_CRC32CheckSum;

ST_PLTE_t;

#pragma pack(1)
typedef struct

        unsigned int        st_mIDAT_ChunkDataLngth;
        unsigned char       st_mIDAT_ChunkType[4];
        unsigned char*      st_mIDAT_ChunkDataPtr;
        unsigned int        st_mIDAT_CRC32CheckSum;

ST_IDAT_t;

#pragma pack(1)
typedef struct

        unsigned int        st_mIEND_ChunkDataLength;
        unsigned char       st_mIEND_ChunkType[4];
        unsigned char *     st_mIEND_ChunkDataPtr;
        unsigned int        st_mIEND_CRC32CheckSum;

ST_IEND_t;

/* Little Endian to Big-Endian API. */
unsigned int BMP2PNG_LitToBigEndian(unsigned int f_BigEndianVal)

    return (((f_BigEndianVal>>24) & 0x000000ff) | ((f_BigEndianVal>>8) & 0x0000ff00) |\
                         ((f_BigEndianVal<<8) & 0x00ff0000) | ((f_BigEndianVal<<24) & 0xff000000));


/* CRC32 API.*/
unsigned int BMP2PNG_CmputeCRC32(unsigned char *p_fIpVal, unsigned int f_IpSize) 

        int l_LoopVar;
        unsigned int l_ByteVal, l_CRCVal, l_MaskVal;
        unsigned int l_TmpIncVar = 0;


        l_CRCVal = 0xFFFFFFFF;

        while (l_TmpIncVar <= f_IpSize) 
        
            // Get next byte.
            l_ByteVal = p_fIpVal[l_TmpIncVar];
            l_CRCVal = l_CRCVal ^ l_ByteVal;

            for (l_LoopVar = 7; l_LoopVar >= 0; l_LoopVar--) 
            
                // Do eight times.
                l_MaskVal = -(l_CRCVal & 1);
                l_CRCVal = (l_CRCVal >> 1) ^ (0xEDB88320 & l_MaskVal);
            

            l_TmpIncVar = l_TmpIncVar + 1;
        

        return ~l_CRCVal;


/* API converts BMP-to-PNG format. */
char *  Convert__40_BMP2PNG(ST_IMAGE_40_HEADER_t * pst_fBMP40ImgHdrVar, FILE * p_ImgFilePtr,\
                                                                    unsigned char * p_fBMP_ColrTble)

        FILE *          l_BMP2PNGFilePtr;

        ST_IHDR_t *     pst_lIHDRChunkVar;

        unsigned char l_PNGSignature[8]=137, 80, 78, 71, 13, 10, 26, 10;
        unsigned int l_BigEndianVal;

        unsigned int l_CRC32Val;
        unsigned char * l_TempCRCBuff;
        unsigned char * l_CRCBuffer;
        unsigned int l_BuffLength = 0;

        unsigned int l_TempIHDRChunkDataLngth;

        pst_lIHDRChunkVar = (ST_IHDR_t *) malloc(sizeof(*pst_lIHDRChunkVar));

        l_BMP2PNGFilePtr = fopen("BMP2PNG2.png","w");

        /* Writing the 1st 8-bytes to the PNG File.*/
        fwrite(l_PNGSignature,1,8,l_BMP2PNGFilePtr);

        fseek(l_BMP2PNGFilePtr,8,SEEK_SET);

        pst_lIHDRChunkVar->st_mChunkDataLngth = 13;

        l_TempIHDRChunkDataLngth = BMP2PNG_LitToBigEndian(13);

        /*Writing the IHDR Chunk Data-Length-Size value to the file.*/
        fwrite(&l_TempIHDRChunkDataLngth,sizeof(unsigned int),1,l_BMP2PNGFilePtr);

        pst_lIHDRChunkVar->st_mChunkType[0] = 'I';
        pst_lIHDRChunkVar->st_mChunkType[1] = 'H';
        pst_lIHDRChunkVar->st_mChunkType[2] = 'D';
        pst_lIHDRChunkVar->st_mChunkType[3] = 'R';

        /* Writing the IHDR-Chunk-Type value to the file.*/
        fwrite( pst_lIHDRChunkVar->st_mChunkType ,sizeof(unsigned char),4,l_BMP2PNGFilePtr);

//      pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mImgWdth = BMP2PNG_LitToBigEndian(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth);
        pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mImgWdth = BMP2PNG_LitToBigEndian(3);

//      pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_ImgHeight = BMP2PNG_LitToBigEndian(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight);
        pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_ImgHeight = BMP2PNG_LitToBigEndian(3);

        if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel <= 8)
        
            pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mBitDepth = pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel;
        
        else if( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 24) || \
                                                (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 32) )
        
            pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mBitDepth = 8;
        
        else
        
            /*No Action.*/
        


        if( pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel <=8 )
        
            pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mColorType = 3;
        
        else if (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 24)
        
            pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mColorType = 2;
        
        else if (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 32)
        
            pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mColorType = 6;
        
        else
        
            /*No Action.*/
        

        pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mCmprsnMthd = 0;
        pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mFltrMthd = 0;
        pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mInterlaceMthd = 0;

        fseek(l_BMP2PNGFilePtr,16,SEEK_SET);

        fwrite(&pst_lIHDRChunkVar->st_IHDR_DataFieldsVar,sizeof(ST_IHDR_DATA_FIELDS_t),1,l_BMP2PNGFilePtr);

        
            /* Framing the data for calculating the 32-bit CRC Checksum.*/
            l_BuffLength = 4+(pst_lIHDRChunkVar->st_mChunkDataLngth);
            l_CRCBuffer = (unsigned char*)malloc(l_BuffLength);


            l_TempCRCBuff = l_CRCBuffer;
            *l_TempCRCBuff++ = pst_lIHDRChunkVar->st_mChunkType[0];
            *l_TempCRCBuff++ = pst_lIHDRChunkVar->st_mChunkType[1];
            *l_TempCRCBuff++ = pst_lIHDRChunkVar->st_mChunkType[2];
            *l_TempCRCBuff++ = pst_lIHDRChunkVar->st_mChunkType[3];

            *l_TempCRCBuff++ = (unsigned char)pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mImgWdth;
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mImgWdth << 8);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mImgWdth << 16);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mImgWdth << 24);

            *l_TempCRCBuff++ = (unsigned char)pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_ImgHeight;
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_ImgHeight << 8);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_ImgHeight << 16);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_ImgHeight << 24);

            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mBitDepth);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mColorType);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mCmprsnMthd);
            *l_TempCRCBuff++ = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mFltrMthd);
            *l_TempCRCBuff   = (unsigned char)(pst_lIHDRChunkVar->st_IHDR_DataFieldsVar.st_mInterlaceMthd);

            // Compute and output CRC
            l_CRC32Val = BMP2PNG_CmputeCRC32(l_CRCBuffer, l_BuffLength);
            l_CRC32Val = BMP2PNG_LitToBigEndian( l_CRC32Val);
            fseek(l_BMP2PNGFilePtr,29,SEEK_SET);

            unsigned int returnVal = fwrite(&l_CRC32Val,sizeof(unsigned int),1,l_BMP2PNGFilePtr);
        

        unsigned char * p_lBMPImgData = pst_fBMP40ImgHdrVar->pst_mImgeData;
//      unsigned int l_BMPImgeDataSze =  ( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth) * \
                                (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight) );

        unsigned int l_BMPImgeDataSze = (3*3)*3;

        ST_IDAT_t * pst_lIDAT_ChunkVar;
        pst_lIDAT_ChunkVar = (ST_IDAT_t *) malloc(sizeof(*pst_lIDAT_ChunkVar));

        unsigned int l_ImgDataSzeIncVar = 0;

        unsigned char * p_IDATBuf;

        unsigned char * p_TempIDATBuf;
        unsigned int l_IDATBufSze;

        if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 24)
        
            fseek(l_BMP2PNGFilePtr,33,SEEK_SET);
            l_BMPImgeDataSze *= 3;

            l_IDATBufSze = 4 + l_BMPImgeDataSze;

            p_IDATBuf = (unsigned char*)malloc(l_IDATBufSze);

            p_TempIDATBuf = p_IDATBuf;

            pst_lIDAT_ChunkVar->st_mIDAT_ChunkDataLngth = BMP2PNG_LitToBigEndian(l_BMPImgeDataSze);

            fwrite(&pst_lIDAT_ChunkVar->st_mIDAT_ChunkDataLngth,sizeof(unsigned int),1,l_BMP2PNGFilePtr);

            pst_lIDAT_ChunkVar->st_mIDAT_ChunkType[0] = 'I';
            pst_lIDAT_ChunkVar->st_mIDAT_ChunkType[1] = 'D';
            pst_lIDAT_ChunkVar->st_mIDAT_ChunkType[2] = 'A';
            pst_lIDAT_ChunkVar->st_mIDAT_ChunkType[3] = 'T';

            fwrite( pst_lIDAT_ChunkVar->st_mIDAT_ChunkType ,sizeof(unsigned char),4,l_BMP2PNGFilePtr);

            fseek(l_BMP2PNGFilePtr,41,SEEK_SET);
            unsigned char ImgeData[27]  =  0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,;

            while(l_ImgDataSzeIncVar <= l_BMPImgeDataSze )
            
                fwrite(ImgeData,sizeof(unsigned char),1,l_BMP2PNGFilePtr);
/*
                fwrite( (p_lBMPImgData+2),sizeof(unsigned char),1,l_BMP2PNGFilePtr);
                *p_TempIDATBuf++ = *(p_lBMPImgData+2);

                fwrite( (p_lBMPImgData+1),sizeof(unsigned char),1,l_BMP2PNGFilePtr);
                *p_TempIDATBuf++ = *(p_lBMPImgData+1);  

                fwrite( (p_lBMPImgData),sizeof(unsigned char),1,l_BMP2PNGFilePtr);
                *p_TempIDATBuf++ = *(p_lBMPImgData);

                p_lBMPImgData += 3;
                l_ImgDataSzeIncVar += 3;
*/
            
        // Compute and output CRC
        unsigned int crc32 = BMP2PNG_CmputeCRC32(p_IDATBuf, l_IDATBufSze);
        fwrite(&crc32,sizeof(unsigned int),1,l_BMP2PNGFilePtr);


        




ST_IMAGE_40_HEADER_t *  ReadBMP40HdrImage(ST_IMAGE_40_HEADER_t * pst_fBMP40ImgHdrVar, \
                                FILE * p_ImgFilePtr)

    unsigned short int  l_ColorTbleSze;
    unsigned char *     l_ColorTbleVal;

    unsigned int        l_ImageDataOffset;

    unsigned int        l_ImageDataSize;
    unsigned int        l_ImageDataSzeIncVar = 1;
    unsigned char *     l_ImageDataPtr;
    unsigned int        l_PixelCount = 1;

    int l_NumOfReadBlks = fread(pst_fBMP40ImgHdrVar,sizeof(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar),1,p_ImgFilePtr);

    printf("\n********************************************************************\n");

    printf("\nPrinting the BMP Image Parameters:\n");

    printf("\nBMP File Header Parameters.\n");
    printf("File Type:\t'BM'\n");
    printf("Total Size of the image:\t%u\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_ImgFileSize);
    printf("Image Data Offset:\t%u\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_ImgDataOffset);

    printf("\nBMP Info Header Parameters.\n");
    printf("Size of the Info-Header:\t'%u-Bytes'.\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_Info40HeaderSze);
    printf("Width of the BMP Image:\t'%d-Pixels'.\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth);
    printf("Height of the BMP Image:\t'%d-Pixels'.\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight);
    printf("Number of Color Planes:\t'%d'.\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_NumOfColrPlnes);
    printf("Number of Bits-Per-Pixel:\t'%d'.\n",pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel);
    printf("Compression Type used for compressing the BMP Raw Image:\t'%d'.\n",\
                                            pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_CmprsnType);
    printf("Horizontal Resolution:\t'%d-Pixels Per Meter'.\n,",\
                                    pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_xResolutn_ppm);

    printf("Vertical Resolution:\t'%d-Pixels Per Meter'.\n,",\
                                    pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_yResolutn_ppm);

    if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_NumOfColrTbleColrs !=0 )
    
        printf("Number of Colors in the color table:\t'%u'.\n",\
                            pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_NumOfColrTbleColrs);        
    

    if( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel <= 8) && \
                (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_NumOfColrTbleColrs !=0) )
    
        rewind(p_ImgFilePtr);
        fseek(p_ImgFilePtr,55,SEEK_SET);

        l_ColorTbleSze = (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_NumOfColrTbleColrs) * 4 ;
        l_ColorTbleVal = (unsigned char*) malloc( l_ColorTbleSze );
        l_NumOfReadBlks = fread(l_ColorTbleVal, l_ColorTbleSze, 1, p_ImgFilePtr);

        if(l_NumOfReadBlks <1)
        
            printf("Couldn't read the Color-Table values from the BMP File.\n");
            return NULL;
        
        else if(l_NumOfReadBlks == 1)
        
            unsigned short int l_ClrTbleIncVar = 0;
            unsigned char * l_TempColorTbleVal = l_ColorTbleVal;
            unsigned short int l_IndexVal = 0;

            printf("\n*****************************************************************************\n");
            printf("Printing the color Table.\n");

            while (l_ClrTbleIncVar <= (l_ColorTbleSze-4) )
            
                printf("Index   '%d' : ", l_IndexVal);
                printf("Blue    ->  '%d'\t",*l_TempColorTbleVal);
                l_TempColorTbleVal++;
                printf("Green   ->  '%d'\t",*l_TempColorTbleVal);
                l_TempColorTbleVal++;
                printf("Red     ->  '%d'\t\n",*l_TempColorTbleVal);
                l_TempColorTbleVal+=2;
                l_ClrTbleIncVar += 4;
                l_IndexVal++;
                       
        
    

    rewind(p_ImgFilePtr);
    l_ImageDataOffset = pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_ImgDataOffset;
    fseek(p_ImgFilePtr,l_ImageDataOffset,SEEK_SET);

    if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 4)
    
        l_ImageDataSize = ( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth) * \
                                            (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight) )/2;

        pst_fBMP40ImgHdrVar->pst_mImgeData = (unsigned char*)malloc(l_ImageDataSize);

        l_ImageDataPtr = pst_fBMP40ImgHdrVar->pst_mImgeData;


        l_NumOfReadBlks = fread(l_ImageDataPtr,1,l_ImageDataSize,p_ImgFilePtr);

        if(l_NumOfReadBlks < 1)
        
            printf("Couldn't read the image data from the file.\n");
            return NULL;
        
    

    else if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 8)
    
        l_ImageDataSize = ( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth) * \
                                            (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight) );

        pst_fBMP40ImgHdrVar->pst_mImgeData = (unsigned char*)malloc(l_ImageDataSize);

        l_ImageDataPtr = pst_fBMP40ImgHdrVar->pst_mImgeData;


        l_NumOfReadBlks = fread(l_ImageDataPtr,l_ImageDataSize,1,p_ImgFilePtr);

        if(l_NumOfReadBlks < 1)
        
            printf("Couldn't read the image data from the file.\n");
            return NULL;
        


    

    else if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 24)
    
        l_ImageDataSize = ( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth) * \
                                            (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight) * 3 );

        pst_fBMP40ImgHdrVar->pst_mImgeData = (unsigned char*)malloc(l_ImageDataSize);

        l_ImageDataPtr = pst_fBMP40ImgHdrVar->pst_mImgeData;


        l_NumOfReadBlks = fread(l_ImageDataPtr,l_ImageDataSize,1,p_ImgFilePtr);

        if(l_NumOfReadBlks < 1)
        
            printf("Couldn't read the image data from the file.\n");
            return NULL;
        
    
    else if(pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_BitsPerPixel == 32)
    
        l_ImageDataSize = ( (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxWdth) * \
                                            (pst_fBMP40ImgHdrVar->st_mBMP40MainHdrVar.st_m40_PxHeight) * 4 );

        pst_fBMP40ImgHdrVar->pst_mImgeData = (unsigned char*)malloc(l_ImageDataSize);

        l_ImageDataPtr = pst_fBMP40ImgHdrVar->pst_mImgeData;


        l_NumOfReadBlks = fread(l_ImageDataPtr,l_ImageDataSize,1,p_ImgFilePtr);

        if(l_NumOfReadBlks < 1)
        
            printf("Couldn't read the image data from the file.\n");
            return NULL;
        
    

    rewind(p_ImgFilePtr);
    Convert__40_BMP2PNG(pst_fBMP40ImgHdrVar,p_ImgFilePtr,l_ColorTbleVal);



int main()

    FILE *      l_ImgeFilePtr;

    l_ImgeFilePtr = fopen("FLAG_B24.BMP","r");

    unsigned short int      l_ImgeFileType;

    unsigned int            l_InfoHdrSze;

    int l_NumofReadBlocks;

    l_NumofReadBlocks = fread(&l_ImgeFileType,2,1,l_ImgeFilePtr);

    if(l_NumofReadBlocks <1)
    
        printf("Couldn't read the bytes from the file.\n");
        return 0;
    


    if(l_ImgeFileType != 19778)
    
        printf("Image Passed is not a BMP file.\n");
        return 0;
    

    fseek(l_ImgeFilePtr,14,SEEK_SET);

    l_NumofReadBlocks = fread(&l_InfoHdrSze, 4, 1, l_ImgeFilePtr);

    if(l_NumofReadBlocks <1)
    
        printf("Couldn't read the bytes from the file.\n");
        return 0;
    


    rewind(l_ImgeFilePtr);
    if( l_InfoHdrSze == 40 )
    
        ST_IMAGE_40_HEADER_t *      pst_Img40HdrVar;

        pst_Img40HdrVar = malloc(sizeof(*pst_Img40HdrVar));

        if(pst_Img40HdrVar == NULL)
        
            printf("There isn't enough memory to allocate for the Image header variable.\n");
            return 0;
        

        ST_IMAGE_40_HEADER_t * pst_l40_ReadAPIReturnVal = ReadBMP40HdrImage(pst_Img40HdrVar, l_ImgeFilePtr);

    

【问题讨论】:

【参考方案1】:

是压缩的PNG文件

是的。

PNG 文件格式中的图像数据如何对齐?

它没有对齐。来自spec,“块数据长度可以是最大字节数;因此,实现者不能假设块在大于字节的任何边界上对齐。”

虽然存在大量图像处理库,但您不必担心这些细节。除非您的目标是专门了解图像文件格式,否则我建议您不要使用自己的转换器。

【讨论】:

我有一个连接到相机的same51微控制器,当点击图片时,它会以BMP文件格式存储它,而在另一边我有一个显示单元,它显示PNG文件格式的图像.所以我必须在不使用 libpng 等库的情况下编写代码。为此,我创建了一个代码来读取 bmp 文件,将图像参数和图像分配给 PNG 块,我已经完成了。但最终的输出结果不会是 PNG 图像。我已附上包含代码的文件。

以上是关于BMP 文件到 PNG 文件转换器的主要内容,如果未能解决你的问题,请参考以下文章

Heic图片转换精灵无损转换JPG/PNG/BMP方法

HEIC文件怎么打开,一键批量将HEIC图片转换JPG/PNG/BMP

HEIC文件怎么打开,一键批量将HEIC图片转换JPG/PNG/BMP

将位图 (bmp) 转换为具有透明度的 png (Windows c++)

将 Png 转换为 Bmp 和位图数组

如何将emf文件转换成png格式