解码带压缩形式的Bitmap(BMP)图像并使用Python可视化解码后实际图像

参考文章




一、数据定义


#define TFT_LCD_PHY_XWIDTH                                                                                                     (320)
#define TFT_LCD_PHY_YHEIGHT                                                                                                    (240)

/* 四字节对齐 */
#pragma pack(1)

/* 位图文件头 */
typedef struct
{
   
    u16 FileType;       /* 文件类型标记 */
    u32 FileSize;       /* 文件大小 */
    u16 Reserve1;       /* 保留1 */
    u16 Reserve2;       /* 保留2 */
    u32 ImgDataOffset;  /* 图像数据偏移 */
}BitMapFileHeader_TypeDef, * pBitMapFileHeader_TypeDef;

/* 位图信息头 */
typedef struct
{
   
    u32 InfoHeaderSize; /* 信息头大小 */
    u32 ImgWidth;       /* 图像宽度 */
    u32 ImgHeight;      /* 图像高度 */
    u16 ColorPlanes;    /* 颜色平面数 */
    u16 PixelsBits;     /* 像素位数 */
    u32 CompresType;    /* 压缩类型 */
    u32 ImgDataSize;    /* 图像数据大小 */
    u32 HorResolut;     /* 水平分辨率 */
    u32 VerResolut;     /* 垂直分辨率 */
    u32 ColorPalette;   /* 调色板大小 */
    u32 ColorImportant; /* 重要颜色数 */
}BitMapInfoHeader_TypeDef, * pBitMapInfoHeader_TypeDef;

typedef struct 
{
   
  u8 B;
  u8 G;
  u8 R;
  u8 A;
}BitmapARGB_TypeDef;

typedef struct
{
   
    BitMapFileHeader_TypeDef FileHeader; /* 位图文件头 */
    BitMapInfoHeader_TypeDef InfoHeader; /* 位图信息头 */
    // u32 * pColorPalette;                 /* 调色板 */
    // u32 * pImgDataWidth;                 /* 图像数据 */
}BitMapInfo_TypeDef, * pBitMapInfo_TypeDef, * BitMapInfo_TypeDef_t;

typedef union 
{
   
    u8 ByteDat;
    struct 
    {
   
        u8 Bit0:1;
        u8 Bit1:1;
        u8 Bit2:1;
        u8 Bit3:1;
        u8 Bit4:1;
        u8 Bit5:1;
        u8 Bit6:1;
        u8 Bit7:1;
    }Bits;
}Type8Bits_TypeDef;
#pragma pack()


typedef struct
{
   
    u32 PaletteData[256];
    u32 DisplayMemory[TFT_LCD_PHY_XWIDTH * TFT_LCD_PHY_YHEIGHT];
    u8  ImageData[1024 * 5];
}BitmapDecode_TypeDef;

BitmapDecode_TypeDef AppBitmapDecode = {
   0};



二、获取调色板数据


/* 获取调色板数据 */
void vGet_Palette_Data(const u8 * pSrcDat, u32 * pColorDat, u16 count)
{
   
    u16 i = 0;
    u32 * pARGB = (u32 *)(pSrcDat + sizeof(BitMapInfo_TypeDef));

    for (i = 0; i < count; ++i)
    {
   
        pColorDat[i] = *pARGB++;
    }
}



三、Bitmap图片解码


/* Bitmap图片解码 */
static u8 ubDecode_Bitmap(const u8 * pSrcDat)
{
   
    const u8 * pDat = NULL;
    Type8Bits_TypeDef bitDat = {
   0};
    BitMapInfo_TypeDef bitmapInfo = {
   0};
    u32 color  = 0, index = 0, temp = 0;
    u32 widthCount = 0, heightCount = 0;
    u16 i = 0, num = 0, count = 0;
    u16 width = 0, height = 0;
    u16 line = 0, colum = 0;


    /* 获取Bitmap信息 */
    memcpy((void *)(&bitmapInfo), (const void *)pSrcDat, sizeof(BitMapInfo_TypeDef));

    /* 获取调色板数据 */
    vGet_Palette_Data(pSrcDat, AppBitmapDecode.PaletteData, bitmapInfo.InfoHeader.ColorPalette);

    /* 显示调色板数据 */
    vShow_ColorPalette_Table(AppBitmapDecode.PaletteData, bitmapInfo.InfoHeader.ColorPalette);

    /* 颜色数据 */
    pDat = pSrcDat + bitmapInfo.FileHeader.ImgDataOffset;

    while(1)
    {
   
        if (*pDat == 0)
        {
   
            pDat++;
            switch (*pDat)
            {
   
                case 0x00: //00 00 行结束
                {
   
                    pDat++;

                    /* 宽度计数不够 */
                    if (bitmapInfo.InfoHeader.ImgWidth >= widthCount)
                    {
   
                        /* 剩余的宽度部分 */
                        temp = bitmapInfo.InfoHeader.ImgWidth - widthCount;
                        if (!bitDat.Bits.Bit0)
                        {
   
                            bitDat.Bits.Bit0 = 1;
                            printf("Tips2......%u\r\n", index);
                        }
                    }
                    else
                    {
   
                        /* 宽度计数超过图像宽度 剩余的宽度部分计算 */
                        temp = bitmapInfo.InfoHeader.ImgWidth - (widthCount % bitmapInfo.InfoHeader.ImgWidth);

                        /* 跨宽度的高度数量 */
                        heightCount += (widthCount / bitmapInfo.InfoHeader.ImgWidth);
                        if (!bitDat.Bits.Bit1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值