BMP文件读写c语言版
时间: 2023-09-29 12:09:47 浏览: 48
以下是读取和写入BMP文件的C语言代码示例:
#### 读取BMP文件
```c
#include <stdio.h>
#include <stdlib.h>
#pragma pack(push, 1)
typedef struct BMPHeader {
uint16_t file_type; // 文件类型,必须为'BM'
uint32_t file_size; // 文件大小
uint16_t reserved1; // 保留
uint16_t reserved2; // 保留
uint32_t data_offset; // 数据偏移量
uint32_t header_size; // 头文件大小
int32_t width; // 图像宽度
int32_t height; // 图像高度
uint16_t planes; // 必须为1
uint16_t bits_per_pixel; // 每个像素的位数
uint32_t compression; // 压缩类型,0为不压缩
uint32_t data_size; // 数据大小
int32_t x_pixels_per_meter;// 水平分辨率
int32_t y_pixels_per_meter;// 垂直分辨率
uint32_t colors_used; // 使用的颜色数
uint32_t important_colors; // 重要颜色数
} BMPHeader;
#pragma pack(pop)
int main() {
FILE *fp;
BMPHeader header;
unsigned char *data;
uint32_t row_size, padding_size;
int i, j;
// 打开文件
fp = fopen("image.bmp", "rb");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
// 读取文件头
fread(&header, sizeof(header), 1, fp);
// 校验文件格式
if (header.file_type != 0x4D42) {
printf("不是BMP文件\n");
fclose(fp);
return 1;
}
// 分配内存
row_size = ((header.bits_per_pixel * header.width + 31) / 32) * 4;
padding_size = row_size - header.width * header.bits_per_pixel / 8;
data = (unsigned char*) malloc(row_size * header.height);
// 读取像素数据
fseek(fp, header.data_offset, SEEK_SET);
for (i = 0; i < header.height; i++) {
fread(&data[i * row_size], header.bits_per_pixel / 8, header.width, fp);
fseek(fp, padding_size, SEEK_CUR);
}
// 关闭文件
fclose(fp);
// 处理像素数据
for (i = 0; i < header.height; i++) {
for (j = 0; j < header.width; j++) {
// 处理像素
// data[i * row_size + j * header.bits_per_pixel / 8] = ...
}
}
// 释放内存
free(data);
return 0;
}
```
#### 写入BMP文件
```c
#include <stdio.h>
#include <stdlib.h>
#pragma pack(push, 1)
typedef struct BMPHeader {
uint16_t file_type; // 文件类型,必须为'BM'
uint32_t file_size; // 文件大小
uint16_t reserved1; // 保留
uint16_t reserved2; // 保留
uint32_t data_offset; // 数据偏移量
uint32_t header_size; // 头文件大小
int32_t width; // 图像宽度
int32_t height; // 图像高度
uint16_t planes; // 必须为1
uint16_t bits_per_pixel; // 每个像素的位数
uint32_t compression; // 压缩类型,0为不压缩
uint32_t data_size; // 数据大小
int32_t x_pixels_per_meter;// 水平分辨率
int32_t y_pixels_per_meter;// 垂直分辨率
uint32_t colors_used; // 使用的颜色数
uint32_t important_colors; // 重要颜色数
} BMPHeader;
#pragma pack(pop)
int main() {
FILE *fp;
BMPHeader header;
unsigned char *data;
uint32_t row_size, padding_size;
int i, j;
// 分配内存
header.width = 640;
header.height = 480;
header.bits_per_pixel = 24;
row_size = ((header.bits_per_pixel * header.width + 31) / 32) * 4;
padding_size = row_size - header.width * header.bits_per_pixel / 8;
header.data_size = row_size * header.height;
header.data_offset = sizeof(header);
header.file_size = header.data_offset + header.data_size;
data = (unsigned char*) malloc(row_size * header.height);
// 填充像素数据
for (i = 0; i < header.height; i++) {
for (j = 0; j < header.width; j++) {
// 填充像素
// data[i * row_size + j * header.bits_per_pixel / 8] = ...
}
}
// 打开文件
fp = fopen("image.bmp", "wb");
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
// 写入文件头
header.file_type = 0x4D42;
header.reserved1 = 0;
header.reserved2 = 0;
header.planes = 1;
header.compression = 0;
header.x_pixels_per_meter = 0;
header.y_pixels_per_meter = 0;
header.colors_used = 0;
header.important_colors = 0;
header.header_size = sizeof(header);
fwrite(&header, sizeof(header), 1, fp);
// 写入像素数据
for (i = 0; i < header.height; i++) {
fwrite(&data[i * row_size], header.bits_per_pixel / 8, header.width, fp);
fwrite(&padding_size, 1, padding_size, fp);
}
// 关闭文件
fclose(fp);
// 释放内存
free(data);
return 0;
}
```