前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++实现图片格式转换

C++实现图片格式转换

原创
作者头像
手撕代码八百里
发布2023-12-29 00:31:01
2660
发布2023-12-29 00:31:01
举报
文章被收录于专栏:猿计划猿计划

前言

在C++中很多地方需要用到图片,图片格式的转换成了难题。不过,可以使用一些库来实现图片格式的转换。其中,OpenCV 是一个广泛使用的计算机视觉库,它提供了许多图像处理和转换的功能。本文将用一些简单的实例来展示如何使用 OpenCV 进行图片格式的转换。

环境安装

如果你不想编译的话,如果你是在Ubuntu下可以使用apt命令安装opencv库:

代码语言:shell
复制
sudo apt-get install libopencv-dev

大题步骤如下:

1、引入opencv的头文件:

#include <opencv2/opencv.hpp>

2、然后使用cv::imread()函数可以读取一张图片;

3、使用cv::imwrite()函数输出转换后的图片;

jpg转png 案例

代码语言:python
复制
#include <opencv2/opencv.hpp>

int main() {
    // 读取输入图片
    cv::Mat inputImage = cv::imread("input.jpg");

    // 检查图片是否成功加载
    if (inputImage.empty()) {
        std::cerr << "Error: Could not read input image." << std::endl;
        return -1;
    }

    // 定义输出图片的文件名和格式
    std::string outputFileName = "output.png";

    // 将图片格式从 JPEG 转换为 PNG
    cv::imwrite(outputFileName, inputImage);

    std::cout << "Image conversion completed. Output file: " << outputFileName << std::endl;

    return 0;
}

YUV直接转BMP

C/C++也可以直接将YUV等数据转成想要的图片,这个时候就需要了解这些编码格式的原理了。例如下面我举例子为YUV转BMP的:

代码语言:c
复制
#include <iostream>
#include <fstream>
#include <vector>

// 保存YUV数据的结构体
struct YUVData {
    std::vector<unsigned char> y;
    std::vector<unsigned char> u;
    std::vector<unsigned char> v;
    int width;
    int height;
};

// 从YUV文件中读取数据
YUVData readYUV(const char* filename, int width, int height) {
    std::ifstream file(filename, std::ios::binary);

    if (!file.is_open()) {
        std::cerr << "Error: Could not open YUV file." << std::endl;
        exit(-1);
    }

    YUVData data;
    data.width = width;
    data.height = height;

    // 计算YUV数据的大小
    size_t size = width * height * 3 / 2;

    // 读取YUV数据
    data.y.resize(width * height);
    file.read(reinterpret_cast<char*>(data.y.data()), width * height);

    data.u.resize(width * height / 4);
    file.read(reinterpret_cast<char*>(data.u.data()), width * height / 4);

    data.v.resize(width * height / 4);
    file.read(reinterpret_cast<char*>(data.v.data()), width * height / 4);

    file.close();

    return data;
}

// 将YUV数据写入BMP文件
void writeBMP(const char* filename, const YUVData& data) {
    std::ofstream file(filename, std::ios::binary);

    if (!file.is_open()) {
        std::cerr << "Error: Could not open BMP file." << std::endl;
        exit(-1);
    }

    // BMP文件头
    const char bmpHeader[] = {
        'B', 'M', // 文件类型
        0, 0, 0, 0, // 文件大小(待填充)
        0, 0, 0, 0, // 保留字段
        54, 0, 0, 0, // 数据偏移

        40, 0, 0, 0, // 信息头大小
        0, 0, 0, 0, // 图像宽度
        0, 0, 0, 0, // 图像高度
        1, 0, // 颜色平面数
        24, 0, // 每像素位数
        0, 0, 0, 0, // 压缩类型
        0, 0, 0, 0, // 图像数据大小
        0, 0, 0, 0, // 水平分辨率
        0, 0, 0, 0, // 垂直分辨率
        0, 0, 0, 0, // 颜色表大小
        0, 0, 0, 0, // 重要颜色数
    };

    // 填充文件大小和图像宽度、高度字段
    *reinterpret_cast<int*>(&bmpHeader[2]) = 54 + data.width * data.height * 3;
    *reinterpret_cast<int*>(&bmpHeader[18]) = data.width;
    *reinterpret_cast<int*>(&bmpHeader[22]) = data.height;

    // 写入BMP文件头
    file.write(bmpHeader, sizeof(bmpHeader));

    // 写入BMP数据(BGR格式)
    for (int y = data.height - 1; y >= 0; --y) {
        for (int x = 0; x < data.width; ++x) {
            unsigned char Y = data.y[y * data.width + x];
            unsigned char U = data.u[(y / 2) * (data.width / 2) + (x / 2)];
            unsigned char V = data.v[(y / 2) * (data.width / 2) + (x / 2)];

            // 转换YUV到BGR
            int C = Y - 16;
            int D = U - 128;
            int E = V - 128;

            int R = std::clamp((298 * C + 409 * E + 128) >> 8, 0, 255);
            int G = std::clamp((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
            int B = std::clamp((298 * C + 516 * D + 128) >> 8, 0, 255);

            // 写入BGR数据
            file.put(static_cast<char>(B));
            file.put(static_cast<char>(G));
            file.put(static_cast<char>(R));
        }
    }

    file.close();
}

int main() {
    // 设置图像的宽度和高度
    int width = 640;
    int height = 480;

    // 读取YUV数据
    YUVData yuvData = readYUV("input.yuv", width, height);

    // 将YUV数据写入BMP文件
    writeBMP("output.bmp", yuvData);

    std::cout << "Conversion completed. Output file: output.bmp" << std::endl;

    return 0;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 环境安装
  • jpg转png 案例
  • YUV直接转BMP
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档