png和bmp图片像素读取(linux)

来源:互联网 发布:成都二手房增值税算法 编辑:程序博客网 时间:2024/05/05 02:19

查找当前目录下的png和bmp图片,将其像素点读取出来压缩进theme.bin中,并将图片的其他信息如宽高压缩前后大小和在theme.bin中的偏移位置保存在bmpaddr.h中,方便在其他代码中读取图片像素信息。

main.c

#include <stdio.h>#include <string.h>#include <dirent.h>#include <stdlib.h>#include <unistd.h>#include <zlib.h>#include <png.h>#include <setjmp.h>#include "Userdefine.h"#include "bmp.h"#define MAX_IMAGE_FILE_NUM (512)#define MAX_NAME_LEN (128)typedef struct{    char acName[MAX_NAME_LEN];    char acBaseName[MAX_NAME_LEN];}IMAGE_NAME;typedef struct{    IMAGE_NAME stImageName[MAX_IMAGE_FILE_NUM];    unsigned int uiTotalPNGFile;    unsigned int uiTotalBMPFile;}IMAGE_FILE;#define FORMAT "#define %-60s"#define HEADER_MARO ("_BMPADDR_H_")#define HEADER_FILE ("bmpaddr.h")#define BIN_FILE ("theme.bin")#define DIR_PATH ("./")IMAGE_FILE stImageFile;FILE *pfHeaderFile = NULL;FILE *pfBinFile = NULL;static int iAddr = 0x0;const unsigned char ucPNGHeadData[] = {0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa};#define BMP_INDEX(x) (MAX_IMAGE_FILE_NUM - x - 1)void HandleFileName(char *pucFileName, unsigned int uiFileLen){    unsigned int uiIndex = 0;    char cTemp = 0;    if(pucFileName == NULL || uiFileLen <= 0)    {        return;    }    for(uiIndex = 0; uiIndex < uiFileLen; uiIndex++)    {        cTemp = pucFileName[uiIndex];        if(cTemp >= 'a' && cTemp <= 'z')        {            cTemp -= 32;        }        else if(!((cTemp >= 'A' && cTemp <= 'Z') || (cTemp >= '0' && cTemp <= '9')))        {            cTemp = '_';        }        pucFileName[uiIndex] = cTemp;    }}void FindAllImageFile(){    struct dirent *pstDirent = NULL;    DIR *pstDir;    IMAGE_NAME *pstTemp = NULL;    BOOL bFound = FALSE;    memset(&stImageFile, 0, sizeof(stImageFile));    pstDir = opendir(DIR_PATH);    while(NULL != (pstDirent = readdir(pstDir)))    {        bFound = FALSE;        if(8 == pstDirent->d_type)        {            if((stImageFile.uiTotalPNGFile + stImageFile.uiTotalBMPFile) < MAX_IMAGE_FILE_NUM)            {                if(strstr(pstDirent->d_name, ".png") || strstr(pstDirent->d_name, ".PNG"))                {                    pstTemp = &(stImageFile.stImageName[stImageFile.uiTotalPNGFile]);                    stImageFile.uiTotalPNGFile++;                    bFound = TRUE;                }                else if(strstr(pstDirent->d_name, ".bmp") || strstr(pstDirent->d_name, ".BMP"))                {                    pstTemp = &(stImageFile.stImageName[MAX_IMAGE_FILE_NUM - stImageFile.uiTotalBMPFile - 1]);                    stImageFile.uiTotalBMPFile++;                    bFound = TRUE;                }                if(bFound)                {                    snprintf(pstTemp->acName, sizeof(pstTemp->acName), "%s", pstDirent->d_name);                    snprintf(pstTemp->acBaseName, sizeof(pstTemp->acBaseName), "%s", pstDirent->d_name);                    HandleFileName(pstTemp->acBaseName, strlen(pstTemp->acBaseName));                }            }        }    }    closedir(pstDir);}void SortImageFile(){    int iIndex = 0;    int iTemp = 0;    IMAGE_NAME stTemp;    int iIndexTemp = 0;    int iTempIndex = 0;    for(iIndex = 0; iIndex < stImageFile.uiTotalPNGFile; iIndex++)    {        stTemp = stImageFile.stImageName[iIndex];        for(iTemp = iIndex + 1; iTemp < stImageFile.uiTotalPNGFile; iTemp++)        {            if(strcmp(stTemp.acBaseName, stImageFile.stImageName[iTemp].acBaseName) > 0)            {                stImageFile.stImageName[iIndex] = stImageFile.stImageName[iTemp];                stImageFile.stImageName[iTemp] = stTemp;                stTemp = stImageFile.stImageName[iIndex];            }        }    }    for(iIndex = 0; iIndex < stImageFile.uiTotalBMPFile; iIndex++)    {        iIndexTemp = BMP_INDEX(iIndex);        stTemp = stImageFile.stImageName[iIndexTemp];        for(iTemp = iIndex + 1; iTemp < stImageFile.uiTotalBMPFile; iTemp++)        {            iTempIndex = BMP_INDEX(iTemp);            if(strcmp(stTemp.acBaseName, stImageFile.stImageName[iTempIndex].acBaseName) > 0)            {                stImageFile.stImageName[iIndexTemp] = stImageFile.stImageName[iTempIndex];                stImageFile.stImageName[iTempIndex] = stTemp;                stTemp = stImageFile.stImageName[iIndexTemp];            }        }    }}void FlipImage(unsigned char * ucImgBuff, int iWidth, int iHeight){    unsigned char *pucLineBuf = NULL;    int iIndexY = 0;    unsigned char *pucHead = NULL;    unsigned char *pucTail = NULL;    pucLineBuf = (unsigned char *)malloc(iWidth * 4);    if(pucLineBuf == NULL)    {        printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);        return;    }    for(iIndexY = 0; iIndexY < iHeight / 2; ++iIndexY)    {        pucHead = ucImgBuff + iIndexY * iWidth * 4;        pucTail = ucImgBuff + (iHeight - iIndexY - 1) * iWidth * 4;        memcpy(pucLineBuf, pucHead, iWidth * 4);        memcpy(pucHead, pucTail, iWidth * 4);        memcpy(pucTail, pucLineBuf, iWidth * 4);    }    free(pucLineBuf);    pucLineBuf = NULL;}void WriteToFile(int iStartAddr, int iWidth, int iHeight, unsigned char *pucPicBuffer, char *acBaseName){    uLongf iDataLenBeforeCompress = iWidth * iHeight * 4;    uLongf iDataLenAfterCompress = compressBound(iDataLenBeforeCompress);    int iRet = 0;    char acTempBuffer[1024];    unsigned char acName[128];    unsigned char *pucCompressData = NULL;    do    {        pucCompressData = (unsigned char *)malloc(iDataLenAfterCompress);        if(pucCompressData == NULL)        {            printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);            break;        }        iRet = compress(pucCompressData, &iDataLenAfterCompress, pucPicBuffer, iDataLenBeforeCompress);        if(Z_OK != iRet)        {            printf("===>[%s, %d]%d\n", __FUNCTION__, __LINE__, iRet);            break;        }        if(pfHeaderFile)        {            int iTempOffset = (4 - (iDataLenAfterCompress % 4));            snprintf(acName, sizeof(acName), "%s", acBaseName);            snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" 0x%x\n", acName, iAddr);            fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);            snprintf(acName, sizeof(acName), "%s_SIZE", acBaseName);            snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n", acName, iDataLenBeforeCompress);            fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);            snprintf(acName, sizeof(acName), "%s_COMPRESS_SIZE", acBaseName);            snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n", acName, iDataLenAfterCompress);            fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);            snprintf(acName, sizeof(acName), "%s_WIDTH", acBaseName);            snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n", acName, iWidth);            fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);            snprintf(acName, sizeof(acName), "%s_HEIGHT", acBaseName);            snprintf(acTempBuffer, sizeof(acTempBuffer), FORMAT" %d\n\n", acName, iHeight);            fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);            if(pfBinFile)            {                char acTemp[8];                memset(acTemp, 0, sizeof(acTemp));//              printf("===>[%s, %d]%x\n", __FUNCTION__, __LINE__, ftell(pfBinFile));                fwrite(pucCompressData, iDataLenAfterCompress, 1, pfBinFile);                fwrite(acTemp, iTempOffset, 1, pfBinFile);            }            iAddr = iAddr + iDataLenAfterCompress + iTempOffset;        }    }while(0);    if(pucCompressData)    {        free(pucCompressData);        pucCompressData = NULL;    }}#define PNG_BYTES_TO_CHECK 4void UseLibPNGToLoadPNGFile(IMAGE_NAME stFileName){    FILE *fp;    png_structp png_ptr;    png_infop info_ptr;    png_bytep* row_pointers;    char buf[PNG_BYTES_TO_CHECK];    int iWidth, iHeight, iIndexX, iIndexY, iTemp, iColorType;    BOOL bGetImageData = FALSE;    unsigned char *pucImageBuffer = NULL;    if(strlen(stFileName.acName) <= 0 || strlen(stFileName.acBaseName) <= 0)    {        printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);        return;    }    do    {        fp = fopen(stFileName.acName, "rb");        if(fp == NULL)        {            break;        }        png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0);        info_ptr = png_create_info_struct(png_ptr);        setjmp(png_jmpbuf(png_ptr));        iTemp = fread(buf, 1, PNG_BYTES_TO_CHECK, fp);        if(iTemp < PNG_BYTES_TO_CHECK)        {            break;        }        iTemp = png_sig_cmp((png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK);        if(iTemp != 0)        {            break;        }        rewind(fp);        png_init_io(png_ptr, fp);        png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);        iColorType = png_get_color_type(png_ptr, info_ptr);        iWidth = png_get_image_width(png_ptr, info_ptr);        iHeight = png_get_image_height(png_ptr, info_ptr);        row_pointers = png_get_rows(png_ptr, info_ptr);//      printf("===>[%s, %d]%d %d %d\n", __FUNCTION__, __LINE__, iWidth, iHeight, iColorType);        pucImageBuffer = (unsigned char *)malloc(iWidth * iHeight * 4);        if(pucImageBuffer == NULL)        {            break;        }        bGetImageData = FALSE;        switch(iColorType)        {            case PNG_COLOR_TYPE_RGB_ALPHA:                for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)                {                    for(iIndexX = 0; iIndexX < iWidth * 4; iIndexX += 4)                    {                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 2) = row_pointers[iIndexY][iIndexX + 0];//r                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 1) = row_pointers[iIndexY][iIndexX + 1];//g                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 0) = row_pointers[iIndexY][iIndexX + 2];//b                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX + 3) = row_pointers[iIndexY][iIndexX + 3];//a                    }                }                bGetImageData = TRUE;                break;            case PNG_COLOR_TYPE_RGB:            {                int iTempIndex = 0;                for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)                {                    for(iIndexX = 0; iIndexX < iWidth * 3;iIndexX +=3)                    {                        iTempIndex = (iIndexX / 3) * 4;                        *(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 2) = row_pointers[iIndexY][iIndexX + 0];                        *(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 1) = row_pointers[iIndexY][iIndexX + 1];                        *(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 0) = row_pointers[iIndexY][iIndexX + 2];                        *(pucImageBuffer + iIndexY * iWidth * 4 + iTempIndex + 3) = 0xff;                    }                }                bGetImageData = TRUE;            }                break;            default:                break;        }        if(bGetImageData)        {//          FlipImage(pucImageBuffer, iWidth, iHeight);            WriteToFile(iAddr, iWidth, iHeight, pucImageBuffer, stFileName.acBaseName);        }    }while(0);    if(pucImageBuffer)    {        free(pucImageBuffer);        pucImageBuffer = NULL;    }    if(fp)    {        fclose(fp);        fp = NULL;    }    png_destroy_read_struct( &png_ptr, &info_ptr, 0);}void LoadBMPFile(IMAGE_NAME stFileName){    FILE *fp = NULL;    BITMAPFILEHEADER stPicHead;    BITMAPINFOHEADER stPicInfoHead;    int iWidth = 0;    int iHeight = 0;    int iBitCount = 0;    int iLineByte = 0;    unsigned char *pucPicBuffer = NULL;    unsigned char *pucImageBuffer = NULL;    if(strlen(stFileName.acName) <= 0 || strlen(stFileName.acBaseName) <= 0)    {        printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);        return;    }    do    {        fp = fopen(stFileName.acName, "rb");        if(fp == NULL)        {            printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);            break;        }        fread(&stPicHead.bfType, sizeof(stPicHead.bfType), 1, fp);        fread(&stPicHead.bfSize, sizeof(stPicHead.bfSize), 1, fp);        fread(&stPicHead.bfReserved1, sizeof(stPicHead.bfReserved1), 1, fp);        fread(&stPicHead.bfReserved2, sizeof(stPicHead.bfReserved2), 1, fp);        fread(&stPicHead.bfOffBits, sizeof(stPicHead.bfOffBits), 1, fp);        if(stPicHead.bfType != 0x4D42)        {            printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);            break;        }        fread(&stPicInfoHead, 1, sizeof(stPicInfoHead), fp);        iWidth = stPicInfoHead.biWidth;        iHeight = stPicInfoHead.biHeight;        iBitCount = stPicInfoHead.biBitCount;//      printf("===>[%s, %d]%d %d %d\n", __FUNCTION__, __LINE__, iWidth, iHeight, iBitCount);//      printf("===>[%s, %d]%d %x\n", __FUNCTION__, __LINE__, stPicInfoHead.biSize, stPicInfoHead.biSizeImage);        if(iBitCount == 24 || iBitCount == 32)        {            int iIndexY = 0;            int iIndexX = 0;            iLineByte = (iWidth*iBitCount / 8 + 3) / 4 * 4;            pucPicBuffer = (unsigned char *)malloc(iHeight * iLineByte);            if(NULL == pucPicBuffer)            {                printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);                break;            }            pucImageBuffer = (unsigned char *)malloc(iHeight * iWidth * 4);            if(NULL == pucImageBuffer)            {                printf("===>[%s, %d]\n", __FUNCTION__, __LINE__);                break;            }            fread(pucPicBuffer, 1, iHeight * iLineByte, fp);//          printf("===>[%s, %d]%x\n", __FUNCTION__, __LINE__, iHeight * iLineByte);            FlipImage(pucPicBuffer, iLineByte / 4, iHeight);            if(iBitCount == 24)            {                for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)                {                    for(iIndexX = 0; iIndexX < iWidth; ++iIndexX)                    {                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 0) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 3 + 0);//b                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 1) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 3 + 1);//g                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 2) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 3 + 2);//r                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 3) = 0xff;                    }                }            }            else if(iBitCount == 32)            {                for(iIndexY = 0; iIndexY < iHeight; ++iIndexY)                {                    for(iIndexX = 0; iIndexX < iWidth; ++iIndexX)                    {                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 0) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 0);//b                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 1) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 1);//g                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 2) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 2);//r                        *(pucImageBuffer + iIndexY * iWidth * 4 + iIndexX * 4 + 3) = *(pucPicBuffer + iIndexY * iLineByte + iIndexX * 4 + 3);//a                    }                }            }            WriteToFile(iAddr, iWidth, iHeight, pucImageBuffer, stFileName.acBaseName);        }    }while(0);    if(fp)    {        fclose(fp);        fp = NULL;    }    if(pucPicBuffer)    {        free(pucPicBuffer);        pucPicBuffer = NULL;    }    if(pucImageBuffer)    {        free(pucImageBuffer);        pucImageBuffer = NULL;    }}void HandleImageFile(){    int iIndex = 0;    IMAGE_NAME stTemp;    int iIndexTemp = 0;    char acTempBuffer[1024];    do    {        pfHeaderFile = fopen(HEADER_FILE, "w");        if(pfHeaderFile == NULL)        {            break;        }        pfBinFile = fopen(BIN_FILE, "w");        if(pfBinFile == NULL)        {            break;        }        snprintf(acTempBuffer, sizeof(acTempBuffer), "#ifndef %s\n", HEADER_MARO);        fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);        snprintf(acTempBuffer, sizeof(acTempBuffer), "#define %s\n\n", HEADER_MARO);        fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);        DEBUG_DEB("Total %d PNG file.\n", stImageFile.uiTotalPNGFile);        for(iIndex = 0; iIndex < stImageFile.uiTotalPNGFile; iIndex++)        {            stTemp = stImageFile.stImageName[iIndex];            UseLibPNGToLoadPNGFile(stTemp);        }        DEBUG_DEB("Total %d BMP file.\n", stImageFile.uiTotalBMPFile);        for(iIndex = 0; iIndex < stImageFile.uiTotalBMPFile; iIndex++)        {            iIndexTemp = BMP_INDEX(iIndex);            stTemp = stImageFile.stImageName[iIndexTemp];            LoadBMPFile(stTemp);        }        snprintf(acTempBuffer, sizeof(acTempBuffer), "#endif\n");        fwrite(acTempBuffer, strlen(acTempBuffer), 1, pfHeaderFile);    }while(0);    if(pfHeaderFile)    {        fclose(pfHeaderFile);        pfHeaderFile = NULL;    }    if(pfBinFile)    {        fclose(pfBinFile);        pfBinFile = NULL;    }}int main(int argc, char *argv[]){    FindAllImageFile();    if(stImageFile.uiTotalBMPFile + stImageFile.uiTotalPNGFile > 0)    {        SortImageFile();        HandleImageFile();    }    return 0;}

bmp.h

#ifndef BMP_H_#define BMP_H_typedef unsigned int   DWORD;typedef unsigned short  WORD;typedef unsigned char  BYTE;typedef  long                   LONG;typedef struct tagBITMAPFILEHEADER {    WORD    bfType;    DWORD   bfSize;    WORD    bfReserved1;    WORD    bfReserved2;    DWORD   bfOffBits;} BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{    DWORD  biSize;    DWORD   biWidth;    DWORD   biHeight;    WORD   biPlanes;    WORD   biBitCount;    DWORD  biCompression;    DWORD  biSizeImage;    DWORD   biXPelsPerMeter;    DWORD   biYPelsPerMeter;    DWORD  biClrUsed;    DWORD  biClrImportant;} BITMAPINFOHEADER;typedef struct tagRGBQUAD { // rgbq   BYTE    rgbBlue;   BYTE    rgbGreen;   BYTE    rgbRed;   BYTE    rgbReserved;} RGBQUAD;#endif /* BMP_H_ */

Userdefine.h

#ifndef USERDEFINE_H_#define USERDEFINE_H_#if 1#define DEBUG_DEB(fmt, arg...) printf("[DEBUG][%s,%d]"fmt, __FUNCTION__, __LINE__, ##arg)#else#define DEBUG_DEB(fmt, arg...)#endif#if 0#define DEBUG_INFO(fmt, arg...) printf("[DEBUG][%s,%d]"fmt, __FUNCTION__, __LINE__, ##arg)#else#define DEBUG_INFO(fmt, arg...)#endif#if 1#define DEBUG_ERR(fmt, arg...) printf("[ERROR][%s,%d]"fmt, __FUNCTION__, __LINE__, ##arg)#else#define DEBUG_ERR(fmt, arg...)#endiftypedef enum{    FALSE,    TRUE,}BOOL;typedef unsigned int U32;#endif /* USERDEFINE_H_ */
0 0
原创粉丝点击