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

#pragma pack(push, 1) typedef struct { unsigned short type; unsigned int size; unsigned short reserved1; unsigned short reserved2; unsigned int offset; } BMPHeader;

typedef struct { unsigned int size; int width; int height; unsigned short planes; unsigned short bit_count; unsigned int compression; unsigned int size_image; int x_pels_per_meter; int y_pels_per_meter; unsigned int clr_used; unsigned int clr_important; } BMPInfoHeader;

typedef struct { unsigned char blue; unsigned char green; unsigned char red; } RGB;

typedef struct { BMPHeader header; BMPInfoHeader info_header; RGB *pixels; } BMPImage; #pragma pack(pop)

BMPImage *read_bmp(const char *filename) { FILE *fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Error: failed to open file %s\n", filename); return NULL; }

BMPImage *image = (BMPImage *) malloc(sizeof(BMPImage));

fread(&image->header, sizeof(BMPHeader), 1, fp);
fread(&image->info_header, sizeof(BMPInfoHeader), 1, fp);

if (image->info_header.bit_count != 24) {
    fprintf(stderr, "Error: unsupported bit count %d\n", image->info_header.bit_count);
    free(image);
    fclose(fp);
    return NULL;
}

image->pixels = (RGB *) malloc(sizeof(RGB) * image->info_header.width * image->info_header.height);

fseek(fp, image->header.offset, SEEK_SET);

for (int y = image->info_header.height - 1; y >= 0; y--) {
    for (int x = 0; x < image->info_header.width; x++) {
        RGB *pixel = &image->pixels[y * image->info_header.width + x];
        fread(pixel, sizeof(RGB), 1, fp);
    }
    fseek(fp, image->info_header.width % 4, SEEK_CUR);
}

fclose(fp);

return image;

}

void write_bmp(const char *filename, BMPImage *image) { FILE *fp = fopen(filename, "wb"); if (!fp) { fprintf(stderr, "Error: failed to open file %s\n", filename); return; }

fwrite(&image->header, sizeof(BMPHeader), 1, fp);
fwrite(&image->info_header, sizeof(BMPInfoHeader), 1, fp);

for (int y = image->info_header.height - 1; y >= 0; y--) {
    for (int x = 0; x < image->info_header.width; x++) {
        RGB *pixel = &image->pixels[y * image->info_header.width + x];
        fwrite(pixel, sizeof(RGB), 1, fp);
    }
    fwrite("\0\0\0", image->info_header.width % 4, 1, fp);
}

fclose(fp);

}

void to_gray(BMPImage *image) { for (int y = 0; y < image->info_header.height; y++) { for (int x = 0; x < image->info_header.width; x++) { RGB *pixel = &image->pixels[y * image->info_header.width + x]; unsigned char gray = (pixel->red + pixel->green + pixel->blue) / 3; pixel->red = pixel->green = pixel->blue = gray; } } }

int main() { BMPImage *image = read_bmp("1.bmp"); if (!image) { return 1; }

to_gray(image);

image->header.type = 0x4D42;
image->header.size = sizeof(BMPHeader) + sizeof(BMPInfoHeader) + image->info_header.width * image->info_header.height * sizeof(RGB);
image->header.offset = sizeof(BMPHeader) + sizeof(BMPInfoHeader);
image->info_header.bit_count = 24;
image->info_header.size_image = image->info_header.width * image->info_header.height * sizeof(RGB);

write_bmp("2.bmp", image);

free(image->pixels);
free(image);

return 0;

}

C语言实现256x256 BMP图像灰度化

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

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