#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;

}

C语言实现BMP彩色图像灰度化

原文地址: https://www.cveoy.top/t/topic/jHKL 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录