当前位置: 首页 > news >正文

c语言 图片.bmp读写示例

1 图片.bmp数据结构

BMP(Bitmap)文件格式是一种简单的位图图像格式,其数据结构分为几个主要部分:文件头、信息头、调色板(可选)和像素数据。下面是各部分的详细说明。

  1. 文件头(File Header)
bfType (2 bytes): 文件类型,通常为'BM'0x42 0x4D)。
bfSize (4 bytes): 文件大小(以字节为单位)。
bfReserved1 (2 bytes): 保留字,通常为0bfReserved2 (2 bytes): 保留字,通常为0bfOffBits (4 bytes): 从文件头到像素数据的偏移量。
  1. 信息头(DIB Header)
biSize (4 bytes): 信息头的大小(通常为40)。
biWidth (4 bytes): 图像宽度(以像素为单位)。
biHeight (4 bytes): 图像高度(以像素为单位)。
biPlanes (2 bytes): 色平面数,通常为1biBitCount (2 bytes): 每个像素的位数(如24位、32位)。
biCompression (4 bytes): 压缩类型(0为不压缩)。
biSizeImage (4 bytes): 图像数据的大小(可以为0)。
biXPelsPerMeter (4 bytes): 水平分辨率(像素每米)。
biYPelsPerMeter (4 bytes): 垂直分辨率(像素每米)。
biClrUsed (4 bytes): 使用的颜色数(0表示使用所有颜色)。
biClrImportant (4 bytes): 重要的颜色数(0表示所有)。
  1. 调色板(Color Palette)
    对于某些格式(如1位或4位色),可能会包含调色板。调色板由颜色索引组成,使用RGB格式(每个颜色占用4个字节,包含蓝、绿、红、保留字节)。

  2. 像素数据(Pixel Data)
    像素数据从bfOffBits指定的位置开始。像素的排列顺序通常是自下而上,从左到右,具体存储格式取决于biBitCount:

24位BMP:每个像素使用3个字节,分别表示蓝色、绿色和红色(BGR格式)。
32位BMP:每个像素使用4个字节(蓝、绿、红、透明度)。

在C语言中,BMP文件格式有一个特定的数据结构。BMP文件分为文件头、信息头和像素数据。下面是BMP文件的基本数据结构:

BMP 文件数据结构

#include <stdint.h>// BMP 文件头
typedef struct {uint16_t bfType;      // 文件类型,通常为 'BM'uint32_t bfSize;      // 文件大小uint16_t bfReserved1; // 保留字段uint16_t bfReserved2; // 保留字段uint32_t bfOffBits;   // 像素数据的偏移量
} BMPFileHeader;

// BMP 信息头

typedef struct {uint32_t biSize;          // 信息头大小int32_t biWidth;          // 图像宽度int32_t biHeight;         // 图像高度uint16_t biPlanes;        // 色平面数,通常为1uint16_t biBitCount;      // 每个像素的比特数(如24位)uint32_t biCompression;   // 压缩类型uint32_t biSizeImage;     // 图像大小int32_t biXPelsPerMeter;   // 水平分辨率int32_t biYPelsPerMeter;   // 垂直分辨率uint32_t biClrUsed;       // 使用的颜色数uint32_t biClrImportant;   // 重要的颜色数
} BMPInfoHeader;

// 像素数据

typedef struct {uint8_t blue;    // 蓝色分量uint8_t green;   // 绿色分量uint8_t red;     // 红色分量
} RGBPix

2 解析 BMP 文件步骤

打开 BMP 文件:

FILE *file = fopen("image.bmp", "rb");
if (!file) {perror("Unable to open file");return;
}

读取文件头:

BMPFileHeader fileHeader;
fread(&fileHeader, sizeof(BMPFileHeader), 1, file);

读取信息头:

BMPInfoHeader infoHeader;
fread(&infoHeader, sizeof(BMPInfoHeader), 1, file);

读取像素数据:
根据 infoHeader.biWidth 和 infoHeader.biHeight 读取像素数据。

int row_padded = (infoHeader.biWidth * 3 + 3) & (~3); // 行填充到4的倍数
RGBPixel *pixels = malloc(infoHeader.biWidth * infoHeader.biHeight * sizeof(RGBPixel));for (int i = 0; i < infoHeader.biHeight; i++) {fread(pixels + (infoHeader.biHeight - i - 1) * infoHeader.biWidth, sizeof(RGBPixel), infoHeader.biWidth, file);fseek(file, row_padded - infoHeader.biWidth * 3, SEEK_CUR);
}

关闭文件:
fclose(file);
注意事项
BMP文件通常以蓝色、绿色、红色(BGR)顺序存储像素。
图片数据行通常是4字节对齐,可能需要填充字节。
确保检查文件类型以确认它是一个合法的BMP文件。

3 c语言 .bmp图像读写示例

#include <stdio.h>
#include <stdlib.h>#define BUF_SIZE 720*1280*3
#define IMG_NAME "fengjing720.bmp"
#define IMG_NEW "x1.bmp"#pragma pack(push, 1) // 让结构体按照1字节对齐,确保读写顺序正确
typedef struct {unsigned short bfType;      // 文件类型unsigned int bfSize;        // 文件大小unsigned short bfReserved1; // 保留字unsigned short bfReserved2; // 保留字unsigned int bfOffBits;     // 像素数据偏移
} BITMAPFILEHEADER;typedef struct {unsigned int biSize;          // 信息头大小int biWidth;                  // 图像宽度int biHeight;                 // 图像高度unsigned short biPlanes;      // 平面数unsigned short biBitCount;    // 每个像素的位数unsigned int biCompression;    // 压缩类型unsigned int biSizeImage;      // 图像大小int biXPelsPerMeter;          // 水平分辨率int biYPelsPerMeter;          // 垂直分辨率unsigned int biClrUsed;       // 使用的颜色索引unsigned int biClrImportant;  // 重要的颜色索引
} BITMAPINFOHEADER;
#pragma pack(pop)BITMAPFILEHEADER bfHeader;
BITMAPINFOHEADER biHeader;void readBMP(const char *filename,unsigned char *data,int size) {FILE *file = fopen(filename, "rb");if (!file) {perror("Failed to open file");return;}// BITMAPFILEHEADER bfHeader;// BITMAPINFOHEADER biHeader;fread(&bfHeader, sizeof(bfHeader), 1, file);fread(&biHeader, sizeof(biHeader), 1, file);if (bfHeader.bfType != 0x4D42) {printf("Not a BMP file.\n");fclose(file);return;}printf("Width: %d, Height: %d Offset:%d\n", biHeader.biWidth, biHeader.biHeight,bfHeader.bfOffBits);// 移动到像素数据部分fseek(file, bfHeader.bfOffBits, SEEK_SET);// 计算像素数据大小//*size = biHeader.biWidth * biHeader.biHeight * 3; // 24位RGB//unsigned char *data = (unsigned char *)malloc(imageSize);if (!data) {printf("Memory allocation failed\n");fclose(file);return;}fread(data, 1,size, file);fclose(file);// 处理像素数据(例如,打印第一个像素的RGB值)printf("First pixel RGB: (%d, %d, %d)\n", data[0], data[1], data[2]);//free(data);
}void writeBMP( const char *filename,unsigned char *data,int size)
{FILE *file = fopen(filename, "wb");if (!file) {perror("Unable to create file");return;}// 写入文件头和信息头fwrite(&bfHeader, sizeof(bfHeader), 1, file);fwrite(&biHeader, sizeof(biHeader), 1, file);// 写入像素数据fwrite(data, 1,size, file);fclose(file);
}int main() {char img_buf[BUF_SIZE];readBMP(IMG_NAME,img_buf,BUF_SIZE);printf("Width: %d, Height: %d Offset:%d\n", biHeader.biWidth, biHeader.biHeight,bfHeader.bfOffBits);writeBMP(IMG_NEW,img_buf,BUF_SIZE);return 0;
}

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 自动化数据采集:Lua爬虫与JSON解析的深度整合
  • 头狼择校小程序
  • PythonStudio 控件使用常用方式(二十一)TTrayIcon
  • 生物制药及化工行业ERP解决方案
  • 汽车免拆诊断案例 | 2010款劳斯莱斯古斯特车中央信息显示屏提示传动系统故障
  • 电动自行车出海黑马Avento独立站拆解(上)丨出海笔记
  • 2024.8.12
  • vue2前端阿里云oss服务端签名直传
  • 非线性RCD负载:电力系统的智能管理
  • 19116 丑数
  • 数据结构与算法 - B树
  • Django基础知识
  • SpringBoot基础(一):快速入门
  • 【对抗性训练】FGM、AWP
  • 使用 mongoexport 导出 JSON 文件和 使用 mongoimport 导入 JSON 文件
  • 【347天】每日项目总结系列085(2018.01.18)
  • 2017年终总结、随想
  • Codepen 每日精选(2018-3-25)
  • CSS中外联样式表代表的含义
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • HTML中设置input等文本框为不可操作
  • java中的hashCode
  • JS题目及答案整理
  • nginx 配置多 域名 + 多 https
  • python学习笔记 - ThreadLocal
  • SQLServer之创建数据库快照
  • SQLServer之索引简介
  • v-if和v-for连用出现的问题
  • vuex 笔记整理
  • vue的全局变量和全局拦截请求器
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 如何使用 JavaScript 解析 URL
  • 译自由幺半群
  • 运行时添加log4j2的appender
  • HanLP分词命名实体提取详解
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • (1)STL算法之遍历容器
  • (2)(2.10) LTM telemetry
  • (9)目标检测_SSD的原理
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (vue)页面文件上传获取:action地址
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • .NET Project Open Day(2011.11.13)
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .NET中分布式服务
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [2016.7.test1] T2 偷天换日 [codevs 1163 访问艺术馆(类似)]
  • [BJDCTF2020]The mystery of ip1