c语言图片灰度化
时间: 2023-07-02 17:15:54 浏览: 121
将彩色图片转换为灰度图片的方法通常是将R、G、B三个通道的值进行加权平均。C语言中可以使用以下代码实现图片的灰度化:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma pack(2) // 结构体字节对齐方式为 2 字节对齐
typedef struct {
unsigned short bfType; // 位图文件类型,必须为 0x4D42
unsigned int bfSize; // 位图文件大小
unsigned short bfReserved1; // 保留字节1
unsigned short bfReserved2; // 保留字节2
unsigned int bfOffBits; // 从文件头到实际位图数据的偏移字节数
} BMPFILEHEADER;
typedef struct {
unsigned int biSize; // 信息头大小
int biWidth; // 图像宽度
int biHeight; // 图像高度
unsigned short biPlanes; // 位平面数,必须为1
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 bmpFileHeader;
BMPINFOHEADER bmpInfoHeader;
RGB **rgbData; // RGB 数组
unsigned char **grayData; // 灰度数组
FILE *fpIn, *fpOut;
int width, height, i, j;
float rWeight = 0.299, gWeight = 0.587, bWeight = 0.114; // 加权平均系数
fpIn = fopen("color.bmp", "rb"); // 以二进制方式读取 BMP 图像文件
fpOut = fopen("gray.bmp", "wb"); // 以二进制方式写入 BMP 图像文件
fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fpIn); // 读取 BMP 文件头
fread(&bmpInfoHeader, sizeof(BMPINFOHEADER), 1, fpIn); // 读取 BMP 信息头
width = bmpInfoHeader.biWidth;
height = abs(bmpInfoHeader.biHeight);
rgbData = (RGB **) malloc(height * sizeof(RGB *)); // 分配 RGB 数组内存
grayData = (unsigned char **) malloc(height * sizeof(unsigned char *)); // 分配灰度数组内存
for (i = 0; i < height; i++) {
rgbData[i] = (RGB *) malloc(width * sizeof(RGB));
grayData[i] = (unsigned char *) malloc(width * sizeof(unsigned char));
}
fseek(fpIn, bmpFileHeader.bfOffBits, SEEK_SET); // 定位到位图数据
// 读取 RGB 数组
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
fread(&rgbData[i][j], sizeof(RGB), 1, fpIn);
}
}
// 将 RGB 数组转换为灰度数组
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
grayData[i][j] = (unsigned char) (rgbData[i][j].r * rWeight + rgbData[i][j].g * gWeight + rgbData[i][j].b * bWeight);
}
}
// 写入 BMP 文件头和信息头
fwrite(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fpOut);
fwrite(&bmpInfoHeader, sizeof(BMPINFOHEADER), 1, fpOut);
// 写入灰度数组
for (i = 0; i < height; i++) {
fwrite(grayData[i], sizeof(unsigned char), width, fpOut);
}
fclose(fpIn);
fclose(fpOut);
for (i = 0; i < height; i++) {
free(rgbData[i]);
free(grayData[i]);
}
free(rgbData);
free(grayData);
return 0;
}
```
这段代码中使用了位图文件头(BMPFILEHEADER)和位图信息头(BMPINFOHEADER),分别描述了 BMP 图像文件的基本信息,例如图像的宽度、高度、每像素位数等。RGB 数组用于存储每个像素的 R、G、B 三个通道的值。灰度数组用于存储每个像素的灰度值,灰度值通过加权平均计算得到。最后将灰度数组写入新的 BMP 图像文件中,从而实现了图片的灰度化。
阅读全文