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

查找当前目录下的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 4
void 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...)
#endif

typedef enum
{
    FALSE,
    TRUE,
}BOOL;

typedef unsigned int U32;

#endif /* USERDEFINE_H_ */
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值