本文基于前两篇文章:
第一篇传送门:http://blog.csdn.net/andromeda_wck/article/details/79173728
第二篇传送门:http://blog.csdn.net/andromeda_wck/article/details/79176944
在第二篇结束是说第三篇写储存,并完善退出,本篇的主要内容如下:
如果图片被修改了,在窗口退出时弹出对话框询问是否需要储存图片,如果没有直接退出,UI界面的保存图像按键槽函数激活。
首先,在头文件添加一个bool值标记图像是否被改变过(最后一个变量):
private:
Ui::ImageProcess *ui;
cv::Mat LoadImage;
QPixmap ImagePixmap;
int Ori_ImageHeight;
int Ori_ImageWidth;
int Ori_ImageDeepth;
int Ori_ImageChannel;
int ImageHeight;
int ImageWidth;
int ImageChannel;
bool b_ClipButton=false;
bool b_ResizeButton=false;
bool b_Modify=false;
对退出程序的槽函数进行添加,当选择Save选项后,调用SaveImage()函数;
QMessageBox msgBox;
if(b_Modify){
msgBox.setText("The Image has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret)
{
case QMessageBox::Save:
SaveImage(LoadImage,"");
break;
case QMessageBox::Discard:
// Don't Save was clicked
break;
case QMessageBox::Cancel:
return;
// Cancel was clicked
break;
default:
// should never be reached
break;
}
exit(0);
}
else
{
exit(0);
}
}
SaveImage函数体如下
函数头:
int SaveImage(cv::Mat Image, QString Saveadd="", int s_width=-1, int s_height=-1);
函数体:
int ImageProcess::SaveImage(cv::Mat Image,QString Saveadd,int s_width,int s_height)
{
if(Saveadd=="")
{
QString Saveadd=QFileDialog::getSaveFileName(this,"SaveImage",QDir::currentPath());
if(Saveadd.isEmpty())
{
QMessageBox::information(this,"warning","content is empty");
return -1;
}
QFile *file=new QFile;
file->setFileName(Saveadd);
bool ok=file->open(QIODevice::WriteOnly);
if(ok){
if(s_width==-1||s_height==-1)
{
Saveadd .replace("/","\\");
std::string cvsaveadd=Saveadd.toStdString();
cv::imwrite(cvsaveadd,Image);
}
else
{
cv::resize(Image,Image,cv::Size(s_width,s_height),0,0);
}
file->close();
delete file;
}
else{
QMessageBox::information(this,"notice","savefailed");
return -1;
}
}
}
上述代码作用是储存图像,打开一个储存对话框,默认工作目录,然后可以选择保存位置,输入保存的文件名字+后缀,将图像保存在指定位置,该函数有三个参数,第一个传入需要保存的MAT,第二个路径,此处路径给一个默认值“”,如果是默认值,咋打开保存对话框选位置(方便以后设置指定地址型的保存方式做准备用),三四参数是保存的图片的宽和高,有默认值-1,如果是-1就是直接按照传入的MAT大小保存(这是为后续可能用到的指定保存尺寸留的)。同样,保存路径也需要通过replace换一下“/”符号。
之后,还有一种情况,就是关闭窗口没有从 退出 按键退出而是直接点窗口的 叉叉之类的,在ImageProcess头文件添加一个关闭事件:
protected:
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent* event);
void MousePosUpdate(QPoint mp);
void ImageShow();
void closeEvent(QCloseEvent *);
完善函数,由于功能和退出一样,所以直接调用退出的槽函数即可:
void ImageProcess::closeEvent(QCloseEvent *event)
{
if (b_Modify)
{
this->on_Exit_Button_clicked();
}
else
{
exit(0);
}
}
UI界面的保存按键也需要激活:
void ImageProcess::on_SaveImage_Button_clicked()
{
SaveImage(LoadImage,"");
b_Modify=false;
}
非常简单,直接调用保存函数。但是记得把b_Modify改为false,不然退出的时候又要问是否保存。
目前的UI界面上对图像会进行修改的只有缩放,所以b_Modify在缩放的按钮里面要设置为true。
导入图像,缩放到500*250 ,然后测试上述的保存,效果如下
全部成功保存。
此处也有个问题,保存的时候需要手动输入保存的后缀,这个主要是因为可以保存为多种格式都是被Opencv支持的,如果只保存一种格式,各位可以再添加一个检查,是否在保存是输入了自己要的后缀,没有的话,就给保存路径添加一个后缀。