这篇文章主要介绍“怎么用C++ OpenCV制作电子相册查看器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用C++ OpenCV制作电子相册查看器”文章能帮助大家解决问题。
我们想要一张张的查看文件夹下的图片,第一步就得读取将该文件夹下的所有图片。
如上图所示,为我创建的文件夹,该文件夹下有14张图片。接下来我们就编写代码读取该文件夹下的所有图片。将读取到的图片存储在images容器。
//读取文件夹下所有图片
string filename = "images";
vector<string>imageList;
glob(filename, imageList);
vector<Mat>images;
for (int i = 0; i < imageList.size(); i++)
{
Mat img = imread(imageList[i]);
images.push_back(img);
}
现在我们已经有了images容器,其实再使用一个for循环就能够一张张读取容器里的图片了。不过这样只能一张张往下读取,直到读取完最后一张图片程序结束。本案例的需求是使用键盘按键“->”向后读取,“<-”向前读取。
我们需要一张白色的画布用来放置图片。为了将所有图片都居中在画布中显示,令画布中心为(cx,cy),当前图片宽width,高height。则该图片相对于画布起点为(x,y)。如下图所示。
//将每一张照片放置画布中心
int x = cx - (width / 2);
int y = cy - (height / 2);
//将照片抠图到画布上,此时照片位于画布中心位置
images[index].copyTo(bg(Rect(x, y, width, height)));
在这里,使用一个判断语句,判断当前图片尺寸是否大于画布尺寸。如果当前图片尺寸大于画布尺寸,则将图片自适应剪切。否则的话,会造成内存溢出。
//如果图片过大,则对其进行裁剪
if (width > canvas.cols || height > canvas.rows)
{
//进行自适应剪切,每次只在原基础上剪切百分之八十
while (true)
{
resize(images[index], images[index], Size(0, 0), 0.8, 0.8, INTER_LINEAR);
if (images[index].cols < canvas.cols&&images[index].rows < canvas.rows)
{
break;
}
}
width = images[index].cols;
height = images[index].rows;
}
根据上述代码我们已经可以将图片显示在画布中心了,接下来就需要使用键盘响应事件控制图片查看。
我们使用方向键“->”控制向下查看,“<-”控制向上查看。具体请看源码注释。
if (key == 2424832)
{
//如果按动键盘‘←'键,则向前查看相片
if (index > 0)//如果图片不是图库中第一张,则允许向前查看
{
cout << "←" << endl;
index--;
}
}
else if (key == 2555904)
{
//如果按动键盘‘→'键,则向后查看相片
if (index < size-1)//如果图片不是图库中最后一张,则允许向后查看
{
cout << "→" << endl;
index++;
}
}
//如果按动键盘‘ESC'键,则退出程序
else if (key == 27)
{
break;
}
如上图所示,至此我们已经完成了案例所想要的效果。请参考源码,注释也比较详细了。
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
//读取文件夹下所有图片
string filename = "images";
vector<string>imageList;
glob(filename, imageList);
vector<Mat>images;
for (int i = 0; i < imageList.size(); i++)
{
Mat img = imread(imageList[i]);
images.push_back(img);
}
//创建画布,用于放置相片
Mat canvas = Mat(Size(1400, 900), CV_8UC3, Scalar::all(255));
//画布中心
int cx = canvas.cols / 2;
int cy = canvas.rows / 2;
int size = images.size();//图库中相片数量
int index = 0; //当前图库中相片索引
while (true)
{
//waitKey无法正常捕捉方向键(上下左右),故使用waitKeyEx
int key = waitKeyEx(0);
if (key == 2424832)
{
//如果按动键盘‘←'键,则向前查看相片
if (index > 0)//如果图片不是图库中第一张,则允许向前查看
{
cout << "←" << endl;
index--;
}
}
else if (key == 2555904)
{
//如果按动键盘‘→'键,则向后查看相片
if (index < size-1)//如果图片不是图库中最后一张,则允许向后查看
{
cout << "→" << endl;
index++;
}
}
//如果按动键盘‘ESC'键,则退出程序
else if (key == 27)
{
break;
}
//将画布拷贝一份,每经一次循环,更新一次图片。
Mat bg = canvas.clone();
//计算每一张图片的宽高
int width = images[index].cols;
int height = images[index].rows;
//如果图片过大,则对其进行裁剪
if (width > canvas.cols || height > canvas.rows)
{
//进行自适应剪切,每次只在原基础上剪切百分之八十
while (true)
{
resize(images[index], images[index], Size(0, 0), 0.8, 0.8, INTER_LINEAR);
if (images[index].cols < canvas.cols&&images[index].rows < canvas.rows)
{
break;
}
}
width = images[index].cols;
height = images[index].rows;
}
//将每一张照片放置画布中心
int x = cx - (width / 2);
int y = cy - (height / 2);
//将照片抠图到画布上,此时照片位于画布中心位置
images[index].copyTo(bg(Rect(x, y, width, height)));
imshow("Demo", bg);
}
destroyAllWindows();
system("pause");
return 0;
}
关于“怎么用C++ OpenCV制作电子相册查看器”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。