写一个BMP图片缩放的代码
时间: 2023-12-01 21:19:46 浏览: 179
bmp位图的缩放代码
3星 · 编辑精心推荐
好的,这里是一个用 C++ 实现的 BMP 图片缩放的示例代码,供你参考:
```cpp
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
using namespace std;
// BMP 文件头结构体
#pragma pack(push, 1)
struct BMPFileHeader {
uint16_t signature; // 文件类型标志
uint32_t file_size; // 文件大小
uint16_t reserved1; // 保留字段1
uint16_t reserved2; // 保留字段2
uint32_t offset; // 数据偏移量
uint32_t header_size; // 信息头大小
int32_t width; // 图像宽度
int32_t height; // 图像高度
uint16_t planes; // 颜色平面数
uint16_t bpp; // 每个像素的位数
uint32_t compression; // 压缩类型
uint32_t data_size; // 数据大小
int32_t x_resolution; // 水平分辨率
int32_t y_resolution; // 垂直分辨率
uint32_t color_used; // 颜色数
uint32_t color_important; // 重要颜色数
};
#pragma pack(pop)
// BMP 图像像素数据结构体
struct BMPImageData {
uint8_t r;
uint8_t g;
uint8_t b;
};
// 缩放 BMP 图像
void scale_bmp_image(const char* input_file, const char* output_file, float scale) {
BMPFileHeader header;
BMPImageData* data = nullptr;
// 读取 BMP 文件头和像素数据
ifstream fin(input_file, ios::binary);
if (!fin.read(reinterpret_cast<char*>(&header), sizeof(header))) {
cerr << "读取文件 " << input_file << " 失败!" << endl;
return;
}
if (header.signature != 0x4D42) {
cerr << "文件 " << input_file << " 不是 BMP 格式!" << endl;
return;
}
data = new BMPImageData[header.width * header.height];
fin.read(reinterpret_cast<char*>(data), header.data_size);
// 计算缩放后的图像大小
int new_width = static_cast<int>(round(header.width * scale));
int new_height = static_cast<int>(round(header.height * scale));
// 分配缩放后的像素数据内存
BMPImageData* new_data = new BMPImageData[new_width * new_height];
// 缩放 BMP 图像
for (int y = 0; y < new_height; y++) {
for (int x = 0; x < new_width; x++) {
// 计算缩放后的像素坐标
float src_x = static_cast<float>(x) / scale;
float src_y = static_cast<float>(y) / scale;
// 双线性插值计算缩放后的像素值
int x1 = static_cast<int>(floor(src_x));
int y1 = static_cast<int>(floor(src_y));
int x2 = static_cast<int>(ceil(src_x));
int y2 = static_cast<int>(ceil(src_y));
float f1 = (x2 - src_x) * (y2 - src_y);
float f2 = (src_x - x1) * (y2 - src_y);
float f3 = (x2 - src_x) * (src_y - y1);
float f4 = (src_x - x1) * (src_y - y1);
BMPImageData& p1 = data[y1 * header.width + x1];
BMPImageData& p2 = data[y1 * header.width + x2];
BMPImageData& p3 = data[y2 * header.width + x1];
BMPImageData& p4 = data[y2 * header.width + x2];
BMPImageData& new_p = new_data[y * new_width + x];
new_p.r = static_cast<uint8_t>(round(p1.r * f1 + p2.r * f2 + p3.r * f3 + p4.r * f4));
new_p.g = static_cast<uint8_t>(round(p1.g * f1 + p2.g * f2 + p3.g * f3 + p4.g * f4));
new_p.b = static_cast<uint8_t>(round(p1.b * f1 + p2.b * f2 + p3.b * f3 + p4.b * f4));
}
}
// 更新 BMP 文件头信息
header.width = new_width;
header.height = new_height;
header.file_size = header.offset + new_width * new_height * sizeof(BMPImageData);
header.data_size = new_width * new_height * sizeof(BMPImageData);
// 写入缩放后的 BMP 图像
ofstream fout(output_file, ios::binary);
fout.write(reinterpret_cast<const char*>(&header), sizeof(header));
fout.write(reinterpret_cast<const char*>(new_data), header.data_size);
// 释放内存
delete[] data;
delete[] new_data;
cout << "文件 " << input_file << " 缩放完成,输出到 " << output_file << "。" << endl;
}
int main(int argc, char* argv[]) {
if (argc != 4) {
cerr << "用法:" << argv[0] << " <输入文件> <输出文件> <缩放比例>" << endl;
return 1;
}
float scale = atof(argv[3]);
if (scale <= 0) {
cerr << "缩放比例必须大于零!" << endl;
return 1;
}
scale_bmp_image(argv[1], argv[2], scale);
return 0;
}
```
这段代码实现了 BMP 图片的缩放功能,使用双线性插值算法进行缩放。你可以通过命令行参数指定输入文件、输出文件和缩放比例,例如:
```bash
./scale_bmp_image input.bmp output.bmp 0.5
```
这条命令会将输入文件 `input.bmp` 缩小一半,输出到文件 `output.bmp` 中。
阅读全文