西电程序设计C++试题第三题---位图图像文件缩放

涉及知识点:文件读写、结构体定义、内存管理、基本图像处理算法、命令行参数

要求:编写一个程序,可以在命令行输入参数,完成指定文件的缩放,并存储到新文件,命令行参数如 (zoom file1.bmp200 file2.bmp)第一个参数为可执行程序名称,第二个参数为原始图像文件名,第三个参数为缩放比例(百分比),第四个参数为新文件名。

思路:

一,写好位图文件头结构体,位图信息头结构体,像素头结构体结构体

二,从文件读取位图图像

三,图像缩放函数

四,将位图图像保存到文件;

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

#pragma pack(push, 1)

// 位图文件头结构体
struct BitmapFileHeader
{
    uint16_t bfType;      // 文件类型,必须为'BM'(0x4D42)
    uint32_t bfSize;      // 文件大小
    uint16_t bfReserved1; // 保留,必须为0
    uint16_t bfReserved2; // 保留,必须为0
    uint32_t bfOffBits;   // 从文件头到位图数据的偏移量
};

// 位图信息头结构体
struct BitmapInfoHeader
{
    uint32_t biSize;         // 信息头大小
    int32_t biWidth;         // 图像宽度
    int32_t biHeight;        // 图像高度
    uint16_t biPlanes;       // 颜色平面数,必须为1
    uint16_t biBitCount;     // 每个像素的位数
    uint32_t biCompression;  // 压缩类型,我们只支持无压缩的位图
    uint32_t biSizeImage;    // 图像数据大小,可以为0
    int32_t biXPelsPerMeter; // 水平分辨率,像素/米
    int32_t biYPelsPerMeter; // 垂直分辨率,像素/米
    uint32_t biClrUsed;      // 使用的颜色索引数,可以为0
    uint32_t biClrImportant; // 重要的颜色索引数,可以为0
};

#pragma pack(pop)

// 像素结构体
struct Pixel
{
    uint8_t blue;
    uint8_t green;
    uint8_t red;
};

// 图像缩放函数
vector<Pixel> ScaleImage(const vector<Pixel> &pixels, int Width, int Height, float newWidth, float newHeight)
{
    vector<Pixel> scaledPixels(newWidth * newHeight);
    float xRatio = static_cast<float>(Width) / newWidth;
    float yRatio = static_cast<float>(Height) / newHeight;

    for (int y = 0; y < newHeight; ++y)
    {
        for (int x = 0; x < newWidth; ++x)
        {
            int oldX = static_cast<int>(x * xRatio);
            int oldY = static_cast<int>(y * yRatio);
            scaledPixels[y * newWidth + x] = pixels[oldY * Width + oldX];
        }
    }

    return scaledPixels;
}

// 从文件读取位图图像
vector<Pixel> LoadBitmap(const string &filename, BitmapInfoHeader &bitmapInfoHeader)
{
    ifstream file(filename, ios::binary);

    BitmapFileHeader fileHeader;
    file.read(reinterpret_cast<char *>(&fileHeader), sizeof(fileHeader));

    if (fileHeader.bfType != 0x4D42) // 是否为位图文件,(0x4d42)标志该文件是位图文件
    {
        cerr << "Invalid bitmap file" << endl;
    }

    file.read(reinterpret_cast<char *>(&bitmapInfoHeader), sizeof(bitmapInfoHeader));

    if (bitmapInfoHeader.biBitCount != 24) // 是否是24位
    {
        cerr << "Unsupported bitmap format" << endl;
    }

    int dataSize = bitmapInfoHeader.biWidth * bitmapInfoHeader.biHeight * sizeof(Pixel); // 位图数据的字节大小
    vector<Pixel> pixels(bitmapInfoHeader.biWidth * bitmapInfoHeader.biHeight);          // 像素总数
    file.read(reinterpret_cast<char *>(pixels.data()), dataSize);

    return pixels;
}

// 将位图图像保存到文件
void SaveBitmap(const string &filename, const vector<Pixel> &pixels, const BitmapInfoHeader &bitmapInfoHeader)
{
    ofstream file(filename, ios::binary);

    BitmapFileHeader fileHeader;
    fileHeader.bfType = 0x4D42;
    fileHeader.bfSize = sizeof(fileHeader) + sizeof(bitmapInfoHeader) + pixels.size() * sizeof(Pixel);
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;

    fileHeader.bfOffBits = sizeof(fileHeader) + sizeof(bitmapInfoHeader);

    file.write(reinterpret_cast<const char *>(&fileHeader), sizeof(fileHeader));
    file.write(reinterpret_cast<const char *>(&bitmapInfoHeader), sizeof(bitmapInfoHeader));
    file.write(reinterpret_cast<const char *>(pixels.data()), pixels.size() * sizeof(Pixel));
}

int main(int argc, char *argv[])
{
    if (string(argv[1]) != "zoom")
    {
        cerr << "Unknown operation" << endl;
        return 1;
    }
    string inputFilename = argv[2];
    int scalePercentage = stoi(argv[3]);
    string outputFilename = argv[4];

    BitmapInfoHeader bitmapInfoHeader;
    vector<Pixel> pixels = LoadBitmap(inputFilename, bitmapInfoHeader);

    int Width = bitmapInfoHeader.biWidth;
    int Height = bitmapInfoHeader.biHeight;

    float newWidth = Width * (scalePercentage / 100.0f);
    float newHeight = Height * (scalePercentage / 100.0f);

    vector<Pixel> scaledPixels = ScaleImage(pixels, Width, Height, newWidth, newHeight);

    bitmapInfoHeader.biWidth = newWidth;
    bitmapInfoHeader.biHeight = newHeight;

    SaveBitmap(outputFilename, scaledPixels, bitmapInfoHeader);

    cout << "Image scaled successfully." << endl;

    return 0;
}

仅供参考

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值