C语言实现BMP彩色图像灰度化
#include <stdio.h> #include <stdlib.h> #include <string.h>
#pragma pack(2) // 2字节对齐
typedef struct { char type[2]; // 文件类型,必须是 'BM' int size; // 文件大小,单位为字节 short reserved1; // 保留字段1,必须为0 short reserved2; // 保留字段2,必须为0 int offset; // 数据偏移量,单位为字节 } bmp_file_header; // BMP文件头
typedef struct { int size; // 信息头大小,单位为字节 int width; // 图像宽度,单位为像素 int height; // 图像高度,单位为像素 short planes; // 图像平面数,必须为1 short bit_count; // 每像素位数 int compression; // 压缩类型,0为不压缩 int image_size; // 图像大小,单位为字节 int x_pels_per_meter; // 水平分辨率,单位为像素/米 int y_pels_per_meter; // 垂直分辨率,单位为像素/米 int clr_used; // 颜色表中的颜色数,为0表示使用所有调色板项 int clr_important; // 重要颜色数,为0表示所有颜色都重要 } bmp_info_header; // BMP信息头
typedef struct { unsigned char blue; // 蓝色分量 unsigned char green; // 绿色分量 unsigned char red; // 红色分量 } rgb; // RGB颜色分量
int main() { FILE *fp_in, *fp_out; bmp_file_header file_header; bmp_info_header info_header; rgb *image_data, *gray_data; int row, col, gray_value;
// 打开文件
fp_in = fopen('1.bmp', 'rb');
if (fp_in == NULL) {
printf('Error: Cannot open file 1.bmp!\n');
return 1;
}
fp_out = fopen('1_gray.bmp', 'wb');
if (fp_out == NULL) {
printf('Error: Cannot create file 1_gray.bmp!\n');
fclose(fp_in);
return 1;
}
// 读取文件头
fread(&file_header, sizeof(bmp_file_header), 1, fp_in);
if (strncmp(file_header.type, 'BM', 2) != 0) {
printf('Error: Not a BMP file!\n');
fclose(fp_in);
fclose(fp_out);
return 1;
}
// 读取信息头
fread(&info_header, sizeof(bmp_info_header), 1, fp_in);
if (info_header.bit_count != 24) {
printf('Error: Not a 24-bit BMP file!\n');
fclose(fp_in);
fclose(fp_out);
return 1;
}
// 分配内存
image_data = (rgb *)malloc(info_header.width * info_header.height * sizeof(rgb));
gray_data = (rgb *)malloc(info_header.width * info_header.height * sizeof(rgb));
// 读取像素数据
fseek(fp_in, file_header.offset, SEEK_SET);
fread(image_data, sizeof(rgb), info_header.width * info_header.height, fp_in);
// 转换为灰度图像
for (row = 0; row < info_header.height; row++) {
for (col = 0; col < info_header.width; col++) {
gray_value = (int)(0.299 * image_data[row * info_header.width + col].red
+ 0.587 * image_data[row * info_header.width + col].green
+ 0.114 * image_data[row * info_header.width + col].blue);
gray_data[row * info_header.width + col].red = gray_value;
gray_data[row * info_header.width + col].green = gray_value;
gray_data[row * info_header.width + col].blue = gray_value;
}
}
// 写入文件头
fwrite(&file_header, sizeof(bmp_file_header), 1, fp_out);
fwrite(&info_header, sizeof(bmp_info_header), 1, fp_out);
// 写入像素数据
fseek(fp_out, file_header.offset, SEEK_SET);
fwrite(gray_data, sizeof(rgb), info_header.width * info_header.height, fp_out);
// 关闭文件
fclose(fp_in);
fclose(fp_out);
// 释放内存
free(image_data);
free(gray_data);
return 0;
}
原文地址: https://www.cveoy.top/t/topic/jHKL 著作权归作者所有。请勿转载和采集!