如何用C语言编程对名字为1bmp的彩色图像 对于每个像素将其RGB值分别读取出来计算其灰度值I=R+G+B3

以下是一个用C语言编程对名字为1.bmp的彩色图像进行灰度处理的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma pack(1) // 按1字节对齐

typedef struct {
    unsigned short bfType;
    unsigned int bfSize;
    unsigned short bfReserved1;
    unsigned short bfReserved2;
    unsigned int bfOffBits;
} BMPFILEHEADER;

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;
} BMPINFOHEADER;

typedef struct {
    unsigned char b;
    unsigned char g;
    unsigned char r;
} RGB;

int main() {
    BMPFILEHEADER fileHeader;
    BMPINFOHEADER infoHeader;
    FILE* fp;
    RGB* pixels;
    int i, j, width, height;
    unsigned char gray;
    
    fp = fopen("1.bmp", "rb");
    if (fp == NULL) {
        printf("Failed to open the file.\n");
        return -1;
    }
    
    fread(&fileHeader, sizeof(BMPFILEHEADER), 1, fp);
    fread(&infoHeader, sizeof(BMPINFOHEADER), 1, fp);
    
    if (fileHeader.bfType != 0x4D42) {
        printf("The file is not a BMP file.\n");
        return -1;
    }
    if (infoHeader.biBitCount != 24) {
        printf("The file is not a 24-bit BMP file.\n");
        return -1;
    }
    
    width = infoHeader.biWidth;
    height = infoHeader.biHeight;
    pixels = (RGB*)malloc(width * height * sizeof(RGB));
    fread(pixels, sizeof(RGB), width * height, fp);
    
    fclose(fp);
    
    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {
            gray = (pixels[i * width + j].r + pixels[i * width + j].g + pixels[i * width + j].b) / 3;
            pixels[i * width + j].r = gray;
            pixels[i * width + j].g = gray;
            pixels[i * width + j].b = gray;
        }
    }
    
    fp = fopen("1_gray.bmp", "wb");
    fwrite(&fileHeader, sizeof(BMPFILEHEADER), 1, fp);
    fwrite(&infoHeader, sizeof(BMPINFOHEADER), 1, fp);
    fwrite(pixels, sizeof(RGB), width * height, fp);
    fclose(fp);
    
    free(pixels);
    
    return 0;
}

这个程序的主要思路是先读取 BMP 文件头和信息头,然后读取像素数据,对每个像素计算灰度值并覆盖原来的 RGB 值,最后将处理后的像素数据写回到一个新的 BMP 文件中。

在程序中,我们首先定义了一个 RGB 结构体来表示一个像素的 RGB 值。然后,我们使用了三个结构体来表示 BMP 文件头、BMP 信息头和像素数据。由于 BMP 文件头和 BMP 信息头中的数据类型是不同的,因此我们需要使用不同的结构体来进行读取。在结构体定义之前,我们使用了一个 #pragma pack(1) 来指定结构体按照 1 字节对齐,这是因为 BMP 文件中的结构体是按照字节对齐的。

接下来,我们打开名字为 1.bmp 的 BMP 文件,并读取文件头和信息头。如果文件头中的文件类型不是 0x4D42,或者信息头中的位深度不是 24,那么我们就认为这不是一个合法的 BMP 文件,程序将会退出。如果读取成功,那么我们就可以根据信息头中的宽度和高度以及位深度来计算出像素数据的大小,并分配足够的内存来存储像素数据。然后,我们读取像素数据,并对每个像素计算灰度值。最后,我们将处理后的像素数据写入一个新的 BMP 文件中,并释放内存。

需要注意的是,这个程序只能处理位深度为 24 的 BMP 文件,如果要处理其他位深度的 BMP 文件,需要进行相应的修改。此外,由于 BMP 文件中的像素数据是按照从下到上、从左到右的顺序存储的,因此在读取和处理像素数据时需要注意这个顺序。

标签: 教育


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