C++ 24位图转换成1位位图代码实现
时间: 2023-05-30 18:03:48 浏览: 223
以下是C语言实现24位图转换成1位位图的代码:
```
#include <stdio.h>
#include <stdlib.h>
#pragma pack(1) // 设置结构体按照1字节对齐
typedef struct {
unsigned short bfType; // 位图文件类型,必须为0x424D,即字符“BM”
unsigned int bfSize; // 位图文件大小,单位为字节
unsigned short bfReserved1; // 保留字段,必须为0
unsigned short bfReserved2; // 保留字段,必须为0
unsigned int bfOffBits; // 数据偏移量,即位图数据距离文件头的偏移量
} BITMAPFILEHEADER;
typedef struct {
unsigned int biSize; // 信息头大小,即40字节
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; // 颜色表使用的颜色数,为0时表示使用所有颜色
unsigned int biClrImportant; // 重要颜色数,为0时表示都重要
} BITMAPINFOHEADER;
typedef struct {
unsigned char b; // 蓝色分量
unsigned char g; // 绿色分量
unsigned char r; // 红色分量
} RGB;
int main() {
FILE *fp24 = fopen("24bit.bmp", "rb"); // 打开24位图
FILE *fp1 = fopen("1bit.bmp", "wb"); // 创建1位位图
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp24); // 读取24位图文件头
fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fp24); // 读取24位图信息头
// 计算1位位图的文件头和信息头
BITMAPFILEHEADER fileHeader1 = fileHeader;
BITMAPINFOHEADER infoHeader1 = infoHeader;
fileHeader1.bfSize = fileHeader.bfOffBits + (infoHeader.biWidth / 8) * infoHeader.biHeight; // 文件大小
fileHeader1.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2; // 数据偏移量
infoHeader1.biBitCount = 1; // 位图每个像素所占位数
infoHeader1.biClrUsed = 2; // 颜色表使用的颜色数
infoHeader1.biClrImportant = 2; // 重要颜色数
// 写入1位位图文件头和信息头
fwrite(&fileHeader1, sizeof(BITMAPFILEHEADER), 1, fp1);
fwrite(&infoHeader1, sizeof(BITMAPINFOHEADER), 1, fp1);
// 写入颜色表
RGB color[2] = {{0, 0, 0}, {255, 255, 255}}; // 黑白两种颜色
fwrite(&color, sizeof(RGB), 2, fp1);
// 读取24位图数据,转换成1位位图数据并写入
int width = infoHeader.biWidth;
int height = infoHeader.biHeight;
int padding = (4 - (width * 3 % 4)) % 4; // 计算每行字节数的填充量
unsigned char data[width * 3 + padding]; // 存储每行24位图数据
unsigned char data1[width / 8 + 1]; // 存储每行1位位图数据
for (int i = 0; i < height; i++) {
fread(&data, sizeof(unsigned char), width * 3 + padding, fp24); // 读取24位图每行数据
int k = 0;
for (int j = 0; j < width; j++) {
int index = j * 3;
unsigned char r = data[index + 2]; // 取出红色分量
unsigned char g = data[index + 1]; // 取出绿色分量
unsigned char b = data[index]; // 取出蓝色分量
if (r == 255 && g == 255 && b == 255) { // 判断是否为白色
data1[k / 8] &= ~(1 << (7 - k % 8)); // 设置为0
} else {
data1[k / 8] |= 1 << (7 - k % 8); // 设置为1
}
k++;
}
fwrite(&data1, sizeof(unsigned char), width / 8 + 1, fp1); // 写入1位位图每行数据
}
fclose(fp24);
fclose(fp1);
return 0;
}
```
阅读全文