基于C++与qt结合opencv编程的图像编辑器,可以完成: 图像原尺寸打开,图像滚动 图像文件自定义保存 图像文件EXIF信息解析 图像操作撤销/重做功能 图像尺寸缩放/扩张 图像旋转 图像亮度调节 图像对比度调节 图像饱和度调节 图像色温调节 图像高光度调节

最近捣鼓了一个基于C++、Qt与OpenCV相结合的图像编辑器,感觉还挺有意思,今天就来跟大家分享分享。
一、图像原尺寸打开与滚动
在Qt中,我们可以利用QGraphicsView和QGraphicsScene来实现图像的显示与滚动。先看代码片段:
cpp
// 创建场景和视图
QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(scene);
// 读取图像
cv::Mat image = cv::imread("your_image.jpg");
if (image.empty()) {
qWarning() << "Could not open or find the image";
return;
}
// 将OpenCV的Mat转换为Qt的QImage
QImage qImage((const unsigned char*)(image.data),
image.cols, image.rows,
image.step, QImage::Format_RGB888).rgbSwapped();
// 添加图像到场景
QGraphicsPixmapItem *item = scene->addPixmap(QPixmap::fromImage(qImage));
// 设置视图属性
view->setScene(scene);
view->setDragMode(QGraphicsView::ScrollHandDrag);
这里首先创建了场景和视图,接着用OpenCV读取图像,然后巧妙地将cv::Mat格式转换为QImage格式,最后添加到场景并设置视图的拖动模式,这样就实现了图像原尺寸打开和滚动的功能。
二、图像文件自定义保存
OpenCV提供了方便的保存函数imwrite,结合Qt的文件对话框来选择保存路径,代码如下:
cpp
QString filePath = QFileDialog::getSaveFileName(this, "Save Image", "", "Images (*.png *.jpg *.bmp)");
if (!filePath.isEmpty()) {
cv::Mat image; // 假设已经有处理后的图像
std::string savePath = filePath.toStdString();
cv::imwrite(savePath, image);
}
这里通过Qt的QFileDialog获取保存路径,然后将其转换为std::string格式,再利用OpenCV的imwrite函数保存图像。
三、图像文件EXIF信息解析
解析EXIF信息需要用到一些额外的库,比如libexif。这里简单介绍下思路,先读取文件,然后解析其中的EXIF数据:
cpp
// 假设已经安装并包含libexif库
ExifData *exif_data = exif_data_new_from_file("your_image.jpg");
if (exif_data) {
ExifEntry *entry = exif_content_get_entry(exif_data->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATETIME_ORIGINAL);
if (entry) {
char *dateTime = exif_entry_get_value(entry);
qDebug() << "拍摄时间: " << QString::fromUtf8(dateTime);
}
exif_data_unref(exif_data);
}
这段代码利用libexif库从图像文件中提取拍摄时间的EXIF信息并打印出来。
四、图像操作撤销/重做功能
实现撤销/重做功能,可以使用命令模式。我们定义一个抽象的命令类,然后每个图像操作对应一个具体的命令类。
cpp
// 抽象命令类
class ImageCommand {
public:
virtual void execute() = 0;
virtual void undo() = 0;
};
// 具体的亮度调节命令类
class BrightnessCommand : public ImageCommand {
public:
BrightnessCommand(cv::Mat &img, int value) : image(img), brightnessValue(value) {}
void execute() override {
// 亮度调节逻辑,这里简单示例
image.convertTo(image, -1, 1, brightnessValue);
}
void undo() override {
// 撤销亮度调节逻辑,与调节逻辑相反
image.convertTo(image, -1, 1, -brightnessValue);
}
private:
cv::Mat ℑ
int brightnessValue;
};
通过这种方式,将每个操作封装成命令,方便实现撤销和重做。
五、图像尺寸缩放/扩张
OpenCV的resize函数可以轻松实现图像尺寸的缩放和扩张:
cpp
cv::Mat originalImage = cv::imread("your_image.jpg");
cv::Mat resizedImage;
// 缩放为原来的0.5倍
cv::resize(originalImage, resizedImage, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR);
这里将图像缩放为原来的0.5倍,cv::INTER_LINEAR是插值方法,用于计算新像素值。
六、图像旋转
OpenCV通过仿射变换实现图像旋转:
cpp
cv::Mat image = cv::imread("your_image.jpg");
cv::Point2f center(image.cols / 2.0, image.rows / 2.0);
cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, 45, 1.0);
cv::Mat rotatedImage;
cv::warpAffine(image, rotatedImage, rotationMatrix, image.size());
这段代码以图像中心为旋转点,顺时针旋转45度。
七、图像亮度、对比度、饱和度、色温、高光度调节
亮度调节
前面在撤销/重做功能中已经展示了简单的亮度调节方式,这里再详细说下。亮度调节本质就是对每个像素的RGB值进行加减操作:
cpp
cv::Mat image = cv::imread("your_image.jpg");
int brightness = 50; // 假设增加50的亮度
cv::Mat adjustedImage;
image.convertTo(adjustedImage, -1, 1, brightness);
对比度调节
对比度调节可以通过改变像素值的范围来实现:
cpp
cv::Mat image = cv::imread("your_image.jpg");
double contrast = 1.5; // 假设增加对比度
int brightness = 0;
cv::Mat adjustedImage;
image.convertTo(adjustedImage, -1, contrast, brightness);
饱和度调节
将图像转换到HSV颜色空间,调节S通道的值来改变饱和度:
cpp
cv::Mat image = cv::imread("your_image.jpg");
cv::Mat hsvImage;
cv::cvtColor(image, hsvImage, cv::COLOR_BGR2HSV);
std::vector<cv::Mat> channels;
cv::split(hsvImage, channels);
// 增加饱和度,这里简单乘以1.5
channels[1] = channels[1] * 1.5;
cv::Mat newHsvImage;
cv::merge(channels, newHsvImage);
cv::Mat adjustedImage;
cv::cvtColor(newHsvImage, adjustedImage, cv::COLOR_HSV2BGR);
色温调节
色温调节相对复杂些,通常需要构建颜色映射表来调整颜色。这里简单示例:
cpp
// 简单的色温调节示例,通过调整RGB通道比例模拟色温变化
cv::Mat image = cv::imread("your_image.jpg");
cv::Mat adjustedImage = image.clone();
for (int i = 0; i < image.rows; ++i) {
for (int j = 0; j < image.cols; ++j) {
cv::Vec3b &pixel = image.at<cv::Vec3b>(i, j);
int b = pixel[0];
int g = pixel[1];
int r = pixel[2];
// 假设降低色温,增加蓝色通道比例
b = static_cast<int>(b * 1.2);
b = std::min(255, b);
adjustedImage.at<cv::Vec3b>(i, j)[0] = b;
}
}
高光度调节
高光度调节可以通过对图像进行直方图均衡化等方式实现:
cpp
cv::Mat image = cv::imread("your_image.jpg");
cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
cv::Mat equalizedImage;
cv::equalizeHist(grayImage, equalizedImage);
// 合并回彩色图像
std::vector<cv::Mat> channels;
cv::split(image, channels);
channels[0] = equalizedImage;
channels[1] = equalizedImage;
channels[2] = equalizedImage;
cv::Mat adjustedImage;
cv::merge(channels, adjustedImage);
通过这些功能的实现,我们打造了一个功能丰富的图像编辑器,结合C++的高效、Qt的界面友好以及OpenCV强大的图像处理能力,让图像处理变得更加有趣和灵活。希望大家也能从中获得一些启发,动手实现自己的图像编辑小工具。
