前言
在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代码运行次数:0复制#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;
}