2,BMP图像类 (1)实现BMP图像处理类 class BMPmanager,需要实现构造和析构,图像读入初始化 (2)实现反色方法Inverse()(红绿反色) (3)实现黑白化方法bw()(超过128为白色,低于128为黑色)
时间: 2024-01-29 13:04:15 浏览: 67
以下是一个简单的 BMP 图像处理类 `BMPmanager` 的实现,包括构造和析构函数、图像读入初始化、反色方法 `Inverse()` 和黑白化方法 `bw()`:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
#pragma pack(2) // 设置结构体按2字节对齐
// BMP 文件头
struct BMPHeader {
char bfType[2]; // 文件类型,必须为 "BM"
int32_t bfSize; // 文件大小,字节为单位
int16_t bfReserved1; // 保留,必须为 0
int16_t bfReserved2; // 保留,必须为 0
int32_t bfOffBits; // 从文件头到像素数据的偏移量,字节为单位
};
// BMP 信息头
struct BMPInfoHeader {
int32_t biSize; // 信息头大小,字节为单位
int32_t biWidth; // 图像宽度,像素为单位
int32_t biHeight; // 图像高度,像素为单位
int16_t biPlanes; // 颜色平面数,必须为 1
int16_t biBitCount; // 每个像素的位数,常用的有 1、4、8、24
int32_t biCompression; // 压缩类型,0 表示不压缩
int32_t biSizeImage; // 像素数据大小,字节为单位
int32_t biXPelsPerMeter;// 水平分辨率,像素每米
int32_t biYPelsPerMeter;// 垂直分辨率,像素每米
int32_t biClrUsed; // 使用的颜色数,如果为 0,则使用所有颜色
int32_t biClrImportant; // 重要的颜色数,如果为 0,则所有颜色都重要
};
// BMP 颜色
struct BMPColor {
uint8_t blue; // 蓝色分量
uint8_t green; // 绿色分量
uint8_t red; // 红色分量
};
// BMP 图像
class BMPmanager {
public:
BMPmanager() {}
BMPmanager(const string& filename) { Load(filename); }
~BMPmanager() { Release(); }
// 读入 BMP 图像
void Load(const string& filename) {
Release();
ifstream fin(filename, ios::binary);
if (!fin.is_open()) {
cerr << "Failed to open file: " << filename << endl;
return;
}
fin.read(reinterpret_cast<char*>(&header), sizeof(BMPHeader));
fin.read(reinterpret_cast<char*>(&info), sizeof(BMPInfoHeader));
if (info.biBitCount == 24) {
data.resize(info.biHeight);
for (int i = 0; i < info.biHeight; ++i) {
data[i].resize(info.biWidth);
fin.read(reinterpret_cast<char*>(data[i].data()), sizeof(BMPColor) * info.biWidth);
}
}
fin.close();
}
// 保存 BMP 图像
void Save(const string& filename) {
if (data.empty()) {
cerr << "No data to save!" << endl;
return;
}
ofstream fout(filename, ios::binary);
if (!fout.is_open()) {
cerr << "Failed to create file: " << filename << endl;
return;
}
int padding = (4 - (info.biWidth * sizeof(BMPColor)) % 4) % 4;
int row_size = info.biWidth * sizeof(BMPColor) + padding;
info.biSizeImage = row_size * info.biHeight;
header.bfSize = header.bfOffBits + info.biSizeImage;
fout.write(reinterpret_cast<char*>(&header), sizeof(BMPHeader));
fout.write(reinterpret_cast<char*>(&info), sizeof(BMPInfoHeader));
for (int i = 0; i < info.biHeight; ++i) {
fout.write(reinterpret_cast<char*>(data[i].data()), sizeof(BMPColor) * info.biWidth);
fout.write(reinterpret_cast<char*>(&padding), padding);
}
fout.close();
}
// 反色
void Inverse() {
if (data.empty()) {
cerr << "No data to process!" << endl;
return;
}
for (int i = 0; i < info.biHeight; ++i) {
for (int j = 0; j < info.biWidth; ++j) {
data[i][j].red = 255 - data[i][j].red;
data[i][j].green = 255 - data[i][j].green;
}
}
}
// 黑白化
void bw() {
if (data.empty()) {
cerr << "No data to process!" << endl;
return;
}
for (int i = 0; i < info.biHeight; ++i) {
for (int j = 0; j < info.biWidth; ++j) {
BMPColor& color = data[i][j];
uint8_t gray = static_cast<uint8_t>(0.299 * color.red + 0.587 * color.green + 0.114 * color.blue);
color.red = color.green = color.blue = (gray > 128 ? 255 : 0);
}
}
}
private:
BMPHeader header;
BMPInfoHeader info;
vector<vector<BMPColor>> data;
// 释放内存
void Release() {
data.clear();
}
};
```
在 `BMPmanager` 类中,使用结构体 `BMPHeader` 和 `BMPInfoHeader` 来定义 BMP 文件头和信息头。在读入 BMP 图像时,使用 `ifstream` 从文件中读取文件头和信息头,并根据位数来读取像素数据。在保存 BMP 图像时,先计算出像素数据大小和文件大小,并将数据写入文件。在图像处理方法中,可以直接操作像素数据进行处理,比如反色和黑白化。在构造和析构函数中,使用 `vector` 来管理像素数据,方便内存的释放和管理。
注意,这里的 BMP 图像处理类仅支持 24 位色的 BMP 图像,如果需要支持其他格式的 BMP 图像,需要进行相应的修改。
阅读全文