C语言实现将彩色BMP位图转化为二值图
时间: 2024-03-09 08:48:54 浏览: 43
实现将彩色BMP位图转化为二值图的方法如下:
1. 打开BMP文件并读取文件头信息和图像数据。
2. 将图像数据按行读取,并将每个像素的RGB值转换为灰度值。
3. 对于每个灰度值,如果其大于等于某个阈值,则将其设置为255(白色),否则设置为0(黑色),即将灰度图像二值化。
4. 将二值化后的图像数据按行写入新的BMP文件中,并更新文件头信息。
下面是一个示例代码,实现了将彩色BMP位图转化为二值图的功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma pack(2) // 结构体按2字节对齐
typedef struct {
char bfType[2]; // 文件类型,必须为BM
unsigned int bfSize; // 文件大小
unsigned short bfReserved1; // 保留字段
unsigned short bfReserved2; // 保留字段
unsigned int bfOffBits; // 偏移量,即文件头大小+调色板大小
} BITMAPFILEHEADER;
typedef struct {
unsigned int biSize; // 信息头大小
int biWidth; // 图像宽度
int biHeight; // 图像高度
unsigned short biPlanes; // 颜色平面数,必须为1
unsigned short biBitCount; // 每个像素的位数
unsigned int biCompression; // 压缩类型,0表示不压缩
unsigned int biSizeImage; // 图像数据大小
int biXPelsPerMeter; // 水平分辨率
int biYPelsPerMeter; // 垂直分辨率
unsigned int biClrUsed; // 调色板中实际使用的颜色数
unsigned int biClrImportant; // 重要的颜色数
} BITMAPINFOHEADER;
#pragma pack() // 恢复默认对齐方式
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s input.bmp output.bmp\n", argv[0]);
return 1;
}
// 打开输入文件
FILE *fIn = fopen(argv[1], "rb");
if (fIn == NULL) {
printf("Failed to open input file!\n");
return 1;
}
// 打开输出文件
FILE *fOut = fopen(argv[2], "wb");
if (fOut == NULL) {
printf("Failed to open output file!\n");
fclose(fIn);
return 1;
}
// 读取文件头信息
BITMAPFILEHEADER fileHeader;
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fIn);
// 读取信息头信息
BITMAPINFOHEADER infoHeader;
fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fIn);
// 判断是否为24位彩色位图
if (infoHeader.biBitCount != 24) {
printf("Only 24-bit color bitmap is supported!\n");
fclose(fIn);
fclose(fOut);
return 1;
}
// 计算每行像素数据的大小(按4字节对齐)
int rowSize = ((infoHeader.biWidth * 3) + 3) & ~3;
// 计算图像数据大小
int dataSize = rowSize * infoHeader.biHeight;
// 读取调色板数据(忽略)
if (fileHeader.bfOffBits != sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)) {
fseek(fIn, fileHeader.bfOffBits - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER), SEEK_CUR);
}
// 分配内存读取图像数据
unsigned char *data = (unsigned char *)malloc(dataSize);
if (data == NULL) {
printf("Failed to allocate memory!\n");
fclose(fIn);
fclose(fOut);
return 1;
}
fread(data, dataSize, 1, fIn);
// 二值化图像数据
unsigned char *binaryData = (unsigned char *)malloc(dataSize);
if (binaryData == NULL) {
printf("Failed to allocate memory!\n");
free(data);
fclose(fIn);
fclose(fOut);
return 1;
}
int threshold = 128; // 阈值
for (int y = 0; y < infoHeader.biHeight; y++) {
for (int x = 0; x < infoHeader.biWidth; x++) {
int index = y * rowSize + x * 3;
int gray = (data[index] * 30 + data[index + 1] * 59 + data[index + 2] * 11) / 100; // 计算灰度值
binaryData[y * rowSize + x] = (gray >= threshold) ? 255 : 0; // 二值化
}
}
// 更新文件头信息
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dataSize;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// 写入文件头信息
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fOut);
fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fOut);
// 写入图像数据
fwrite(binaryData, dataSize, 1, fOut);
// 关闭文件并释放内存
free(data);
free(binaryData);
fclose(fIn);
fclose(fOut);
printf("Done!\n");
return 0;
}
```
该代码使用了灰度化和阈值化的方法将彩色BMP位图转化为二值图,其中灰度值的计算使用了RGB加权平均法。可以通过调整阈值来控制二值化的效果。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)