C++批量图片转换工具:多种格式转WebP
这是一个刚写的 C++ 实现的批量图片转换工具,能够将文件夹中的 JPG、JPEG、PNG 等格式图片转换为 WebP 格式。还可以,将就着用呗。
方案选择
有以下几种方案:
OpenCV 方案:简单易用,适合快速开发
FreeImage 方案:专为图像处理设计,支持多种格式
CxImage 方案:功能强大,支持多种格式转换
但是我懒,就只使用OpenCV来实现呗,因为这玩意安装简单、文档丰富,且能满足基本需求。如果需要更专业的解决方案,可以考虑 FreeImage 或 CxImage。
实现代码
#include <iostream>
#include <vector>
#include <filesystem>
#include <opencv2/opencv.hpp>
namespace fs = std::filesystem;
// 转换单张图片为WebP格式
bool convertToWebP(const fs::path& inputPath, const fs::path& outputPath, int quality = 80) {
try {
// 读取原始图片
cv::Mat image = cv::imread(inputPath.string());
if (image.empty()) {
std::cerr << "无法读取图片: " << inputPath << std::endl;
return false;
}
// 准备输出参数
std::vector<int> compression_params;
compression_params.push_back(cv::IMWRITE_WEBP_QUALITY);
compression_params.push_back(quality); // 质量参数(0-100)
// 写入WebP格式
bool success = cv::imwrite(outputPath.string(), image, compression_params);
if (!success) {
std::cerr << "转换失败: " << inputPath << std::endl;
return false;
}
return true;
} catch (const cv::Exception& e) {
std::cerr << "OpenCV异常: " << e.what() << std::endl;
return false;
}
}
// 批量转换文件夹中的图片
void batchConvertToWebP(const fs::path& inputDir, const fs::path& outputDir, int quality = 80) {
// 确保输出目录存在
if (!fs::exists(outputDir)) {
fs::create_directories(outputDir);
}
// 支持的图片扩展名
const std::vector<std::string> supportedExtensions = {".jpg", ".jpeg", ".png", ".bmp", ".tif", ".tiff"};
// 遍历输入目录
int convertedCount = 0;
for (const auto& entry : fs::directory_iterator(inputDir)) {
if (entry.is_regular_file()) {
fs::path inputPath = entry.path();
std::string extension = inputPath.extension().string();
// 转换为小写比较
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
// 检查是否支持该格式
if (std::find(supportedExtensions.begin(), supportedExtensions.end(), extension) != supportedExtensions.end()) {
// 构造输出路径
fs::path outputPath = outputDir / inputPath.stem();
outputPath += ".webp";
// 转换图片
if (convertToWebP(inputPath, outputPath, quality)) {
std::cout << "转换成功: " << inputPath << " -> " << outputPath << std::endl;
convertedCount++;
}
}
}
}
std::cout << "转换完成! 共转换了 " << convertedCount << " 张图片." << std::endl;
}
int main(int argc, char* argv[]) {
// 检查参数
if (argc < 3) {
std::cout << "用法: " << argv[0] << " <输入目录> <输出目录> [质量(0-100), 默认80]" << std::endl;
return 1;
}
// 获取参数
fs::path inputDir(argv[1](@ref);
fs::path outputDir(argv[2](@ref);
int quality = 80;
if (argc >= 4) {
quality = std::atoi(argv[3](@ref);
quality = std::max(0, std::min(100, quality)); // 确保质量在0-100范围内
}
// 检查输入目录是否存在
if (!fs::exists(inputDir) || !fs::is_directory(inputDir)) {
std::cerr << "错误: 输入目录不存在或不是一个目录: " << inputDir << std::endl;
return 1;
}
// 执行批量转换
batchConvertToWebP(inputDir, outputDir, quality);
return 0;
}使用说明
编译要求:
C++17 或更高版本
OpenCV 库(建议 4.x 版本)
支持 filesystem 的编译器
编译命令(以 g++ 为例):
g++ -std=c++17 -o image_converter image_converter.cpp `pkg-config --cflags --libs opencv4`运行命令:
./image_converter 输入目录 输出目录 [质量参数]质量参数可选,范围 0-100,默认 80
支持的输入格式:
JPG/JPEG
PNG
BMP
TIFF/TIF
替代方案
如果你需要更专业的解决方案,可以考虑以下替代实现:
1. 使用FreeImage库
#include <iostream>
#include <vector>
#include <filesystem>
#include <FreeImage.h>
namespace fs = std::filesystem;
bool convertToWebP(const fs::path& inputPath, const fs::path& outputPath, int quality = 80) {
// 初始化FreeImage
FreeImage_Initialise();
// 确定文件格式
FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(inputPath.string().c_str());
if (fif == FIF_UNKNOWN) {
fif = FreeImage_GetFIFFromFilename(inputPath.string().c_str());
}
if (fif == FIF_UNKNOWN) {
std::cerr << "未知的图像格式: " << inputPath << std::endl;
return false;
}
// 加载图像
FIBITMAP* dib = FreeImage_Load(fif, inputPath.string().c_str());
if (!dib) {
std::cerr << "无法加载图像: " << inputPath << std::endl;
return false;
}
// 设置WebP质量
FreeImage_SetMetadata(FIMD_WEBP_QUALITY, dib, "quality", std::to_string(quality).c_str());
// 保存为WebP
BOOL success = FreeImage_Save(FIF_WEBP, dib, outputPath.string().c_str());
FreeImage_Unload(dib);
// 释放FreeImage资源
FreeImage_DeInitialise();
return success;
}
// batchConvertToWebP和main函数与OpenCV版本类似2. 使用CxImage库
#include <iostream>
#include <vector>
#include <filesystem>
#include "ximage.h"
namespace fs = std::filesystem;
bool convertToWebP(const fs::path& inputPath, const fs::path& outputPath, int quality = 80) {
CxImage image;
if (!image.Load(inputPath.string().c_str())) {
std::cerr << "无法加载图像: " << inputPath << std::endl;
return false;
}
image.SetCodecOption(quality); // 设置质量
return image.Save(outputPath.string().c_str(), CXIMAGE_FORMAT_WEBP);
}
// batchConvertToWebP和main函数与OpenCV版本类似性能优化建议
多线程处理:对于大量图片,可以使用多线程加速转换过程
批量处理:如 OpenCL 方案所示,可以利用 GPU 加速处理
内存优化:对于大图片,考虑分块处理
错误处理增强:添加更详细的错误日志和恢复机制
总结
以上代码提供了一个完整的 C++ 解决方案,用于将文件夹中的多种图片格式批量转换为 WebP 格式。OpenCV 版本简单易用,适合大多数场景。如果需要更专业的处理或更好的格式支持,可以考虑 FreeImage 或 CxImage 方案。
C++批量图片转换工具:多种格式转WebP
https://uniomo.com/archives/c-pi-liang-tu-pian-zhuan-huan-gong-ju-duo-zhong-ge-shi-zhuan-webp