• bmp图片处理


    bmp图片基础

    BMP格式内的数据分为三到四个部分,依次是:

    1. 文件信息头 (14字节)存储着文件类型,文件大小等信息
    2. 图片信息头 (40字节)存储着图像的尺寸,颜色索引,位平面数等信息
    3. 调色板 (由颜色索引数决定)【24位及以上可以没有此信息】
    4. 位图数据 (由图像尺寸决定)每一个像素的信息在这里存储

    一般的bmp图像都是24位,也就是真彩。每8位为一字节,24位也就是使用三字节来存储每一个像素的信息,三个字节对应存放r,g,b三原色的数据,每个字节的存贮范围都是0-255。那么以此类推,32位图即每像素存储r,g,b,a(Alpha通道,存储透明度)四种数据。8位图就是只有灰度这一种信息,还有二值图,它只有两种颜色,黑或者白。

    1. 计算调色板大小
    位图起始位置偏移量 - 54
    
    • 1
    2. 计算每行的字节数

    bmp图片每一行都是4的倍数,不足添加无效位
    即一行的字节数等于图片宽度(一行像素点总数)* 像素点占的位数
    行字节数 = 位图宽 + ((4 - (位图宽 * 像素点位数 / 8)%4))%4

    lineByte = bmp.width_x + ((4-(bmp.width_x*bmp.deepth/8)%4))%4;
    
    • 1

    bmpFormat.h

    #ifndef _BMPFORMAT_H_
    #define _BMPFORMAT_H_
    
    typedef unsigned char BYTE;  // 定义BYTE为一个字节的类型
    typedef unsigned short WORD; // 定义WORD为两个字节的类型
    typedef unsigned int DWORD;  // 定义DWORD为四个字节的类型
    
    #pragma pack(2) // 按两个字节对齐
    /* BMP文件头结构体,共14字节 */
    typedef struct BMP_FILE_HEADER
    {
        WORD bfType;      // 文件标识符,类型
        DWORD bfSize;     // 文件的大小,字节为单位
        WORD bfReserved1; // 保留值,必须设置为0
        WORD bfReserved2; // 保留值,必须设置为0
        DWORD bfOffset;   // 文件头的最后到图像数据位开始的偏移量
    } BMPFILEHEADER;
    //#pragma pack(pop)
    
    /* 位图信息头,共40字节*/
    typedef struct BMP_INFO_HEADER
    {
        DWORD biInfoSize;      // 位图信息头的大小
        DWORD biWidth;         // 图像的宽度,像素单位
        DWORD biHeight;        // 图像的高度,像素单位
        WORD biPlanes;         // 图像的平面数,总为1
        WORD biBitCount;       // 每个像素的位数,及比特数1、4、8、16、24或32
        DWORD biCompression;   // 压缩类型
        DWORD biImageSize;     // 图像的大小,以字节为单位
        DWORD biXPelsPerMeter; // 水平分辨率
        DWORD biYPelsPerMeter; // 垂直分辨率
        DWORD biClrUsed;       // 使用的色彩数
        DWORD biClrImportant;  // 重要的颜色数
    } BMPINFOHADER;
    
    /* 自定义的存放颜色数据的结构体 */
    typedef struct BMP_BASE
    {
        unsigned char *buf; //用来存放颜色的数据
        int width_x;        //宽
        int height_y;       //高
        int deepth;         //像素的位数及biBitCount
    } BMPBASE;
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    bmp.c

    功能将8位bmp图片解析读取并写入到新的文件中

    /*********************************************************************
    *    处理8位bmp位图
    *********************************************************************/
    #include 
    #include 
    #include 
    #include "bmpFormat.h"
    
    int main()
    {
        FILE *in;                    // 定义一个输入文件指针
        FILE *out;                   // 定义一个输出文件指针
        BMPFILEHEADER bmpFileHeader; // 定义一个BMP文件头
        BMPINFOHADER bmpInfoHeader;  // 定义一个BMP位图信息头
        BMPBASE bmp;                 // 定义一个存储颜色信息
        unsigned char *tmp;          // 调色板(颜色表)信息缓冲区
        int lineByte;				 // 一行字节数
        int biPaletteSize;           // 调色板信息大小    /* 打开原始图片并读取有关数据 */
    
        if ((in = fopen("in.bmp", "rb")) == NULL) //打开图片
        {
            printf("Cann't open the file!\n");
            return 0;
        }
    
        fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, in);  //读取文件头信息
    
        fread(&bmpInfoHeader, sizeof(BMPINFOHADER), 1, in);  //读位图信息头信息
    
        //读取颜色表信息
        biPaletteSize = bmpFileHeader.bfOffset - 54;//BMP文件头信息,共14字节;位图信息头,共40字节
        tmp = (unsigned char*)malloc(biPaletteSize);
        fread(tmp, biPaletteSize, 1, in);
        
        ///将原始图片色彩信息存储到Bmpbase
        bmp.width_x = bmpInfoHeader.biWidth; //获取图片宽、高、每个像素所占位数等信息
        bmp.height_y = bmpInfoHeader.biHeight;
        bmp.deepth = bmpInfoHeader.biBitCount;
       
        lineByte = bmp.width_x + ((4-(bmp.width_x*bmp.deepth/8)%4))%4;  //定义变量,计算图像每行像素所占字节数,每行都是4的整数倍,不足使用无效字节填充
        bmp.buf = (unsigned char *)malloc(lineByte * bmp.height_y); //创建一定大小的数组空间存放颜色数据
        fread(bmp.buf, 1, lineByte * bmp.height_y, in);             //将颜色数据读入数组空间
    
    
        /* 创建新图,并写入信息*/
        if ((out = fopen("out.bmp", "wb")) == NULL) //打开新文件
        {
            printf("Cann't creat new file!\n");
            return 0;
        }
        
        //写文件头进文件
        fwrite(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, out);
    
         //写位图信息头进文件
        fwrite(&bmpInfoHeader, sizeof(BMPINFOHADER), 1, out);
    
        //写调色板信息
        fwrite(tmp, biPaletteSize, 1, out);
    
        //写颜色数据进文件
        fwrite(bmp.buf, lineByte * bmp.height_y, 1, out);
    
    #if 0
        printf("biPaletteSize:%d\n", biPaletteSize);//颜色表大小
        printf("width_x:%d width_y:%d\n", bmp.width_x, bmp.height_y);//图片宽高
        printf("lineByte:%d\n", lineByte); //行字节数
        printf("bmp.deepth:%d\n", bmp.deepth); //一个像素点占用的位数
    #endif 
    
        fclose(in);
        fclose(out);
        free(tmp);
        free(bmp.buf);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
  • 相关阅读:
    用于Linux日常系统管理任务地sed命令解析
    周计划&周记录:2022年8月1日-2022年8月7日
    设计模式 之 创建型模式
    MacOS 中Boost的安装和使用
    javaweb(三)
    Mac下通过nvm管理node
    根据json生成Java类
    Accelerate 0.24.0文档 三:超大模型推理(内存估算、Sharded checkpoints、bitsandbytes量化、分布式推理)
    把样式直接转化成 Tailwindcss Plugin 吧
    词法分析基础
  • 原文地址:https://blog.csdn.net/weixin_54178481/article/details/127696162