基于Qt 的可视化图片处理程序——图片的加载与保存
void MainWindow::loadPixmap()
{
QImage img,image;
QPixmap pixmap;
LoadPicPath = QFileDialog::getOpenFileName(this,tr("选择图片"),"C://Users//ppqpp//Pictures","Pic Files (*.jpg;*.jeg;*.png;*.gif);;All Files (*);");
img.load(LoadPicPath);
image = img.scaled(ui->PicLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); // Qt::KeepAspectRatio 按比例缩放 Qt::SmoothTransformation 缩放不失帧
pixmap = QPixmap::fromImage(image);
ui->PicLabel->clear();
ui->PicLabel->setPixmap(pixmap);
}
QLabel加载图片方式之一
QPixmap pixmap(":/images/abc.jpg"); //通过构造函数载入图片方式
pixmap.load(":/images/ab.jpg"); //另外一种载入图片方式
pixmap.scaled(ui->label1->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
ui->label1->setScaledContents(true);
ui->label1->setPixmap(pixmap);
Chapter1 基于Qt 的可视化图片处理程序——图片的加载与保存
图片的加载
点击按钮选择文件
首先要确定,使用 Qt 中 QFileDialog 库中的 getLoadFile 进行选择文件。
代码如下:
LoadPicPath = QFileDialog::getOpenFileName(this,"选择图片","C://Users//ppqpp//Pictures","Pic Files (*.jpg;*.jeg;*.png;*.gif);;All Files (*);");
// getOpenFile 参数包含窗口的父类,窗口名称,默认选择地址,和要选择的文件格式
// 设置文件扩展名过滤,注意用双分号间隔
运行效果如下:
图片加载到 Label
在 Qt 中,我们一种最常用的图片加载方式就是使用 QImage 库,此处我们通过 QImage 加载图片,之后通过加载到 QPixmap 中,最终显示在 Label 上
首先声明 QImage 变量,并加载我们指定路径下的图片:
QImage img;
img.load(LoadPicPath);
// LoadPicPath 是我们选择的文件的路径及名称
在成功加载图片之后,我们通过将图加载到 QPixmap 上,最终将图片显示在 Label 上:
image = img.scaled(this->ui->PicLabel->size(),Qt::KeepAspectRatio, Qt::SmoothTransformation);
/*
首先要按照比例合理缩放图片的大小,并且在缩放的过程中要保证图片不失帧
Qt::KeepAspectRatio 按比例缩放 Qt::SmoothTransformation 缩放不失帧
*/
QPixmap pixmap = QPixmap::fromImage(image);
// 在pixmap中加载图片
this->ui->PicLabel->setPixmap(pixmap)
// 将图片显示到 Label 中
运行效果如下:
完整代码
void MainWindow::Load(){ // 加载图片
QImage img;
img.load(LoadPicPath);
w_initial = img.width();
h_initial = img.height();
image = img.scaled(this->ui->PicLabel->size(),Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap = QPixmap::fromImage(image);
// Qt::KeepAspectRatio 按比例缩放 Qt::SmoothTransformation 缩放不失帧
this->ui->PicLabel->clear();
this->ui->PicLabel->setPixmap(pixmap);
this->getpixel();
}
void MainWindow::on_actionLoadPic_triggered() // 点击事件
{
if(LoadPicPath == ""){
if_load_save = false;
}
else{
qDebug()<<LoadPicPath;
if_load_save = true;
qDebug()<<"if_load_save = "<<if_load_save;
}
LoadPicPath = QFileDialog::getOpenFileName(this,"选择图片","C://Users//ppqpp//Pictures","Pic Files (*.jpg;*.jeg;*.png;*.gif);;All Files (*);");
if(if_load_save){
savedialog->show();
savedialog->exec();
}
else{
// this->init_all();
this->Load();
}
}
图片的保存
点击按钮保存路径
与加载图片的方法一致,使用 getSaveFile 函数选择要保存图片的路径:
MainWindow::SavePicPath = QFileDialog::getSaveFileName(this,"C://Users//ppqpp//Pictures",MainWindow::LoadPicPath,"Pic Files (*);");
运行效果如下:
保存图片
在保存图片之前,我们需要先提取要进行保存的目标图片,通过一种类似于截屏的方式 pixmap()->toImage() 对图片进行提取,然后缩放到原来的大小,最后进行保存
代码如下:
QImage img = this->ui->PicLabel->pixmap()->toImage().scaled(w_initial,h_initial,Qt::KeepAspectRatio, Qt::SmoothTransformation);
img.save(SavePicPath);
完整代码
void SaveDialog::on_pushButton_clicked()
{
MainWindow::SavePicPath = QFileDialog::getSaveFileName(this,"C://Users//ppqpp//Pictures",MainWindow::LoadPicPath,"Pic Files (*);");
this->ui->PathEdit->setText(MainWindow::SavePicPath);
}
void SaveDialog::on_SaveButton_clicked()
{
qDebug()<<"Save new Pic"<<MainWindow::LoadPicPath;
if(this->ui->PathEdit->text() != ""){
emit to_save();
if(MainWindow::if_load_save){
qDebug()<<"if_load_save = "<<MainWindow::if_load_save;
qDebug()<<"save_to_load";
MainWindow::if_load_save = false;
emit save_to_load();
}
this->close();
}
}
void MainWindow::Cover_save(){
qDebug()<<"Cover_save";
QImage img = this->ui->PicLabel->pixmap()->toImage().scaled(w_initial,h_initial,Qt::KeepAspectRatio, Qt::SmoothTransformation);
img.save(SavePicPath);
}
Chapter2 Qt使用QImage保存成JPG(PNG)图像到本地
原文链接:https://blog.csdn.net/hml111666/article/details/122500834
一、QImage类简介
- QImage提供了一个与硬件无关的图像表示方法,允许直接访问像素数据,可用作绘图设备。
- QImage类支持QImage::Format、enum描述的多种图像格式。包括8-bit, 32-bit 和alpha混合图像
- QImage 提供很多可以用于获取图像信息和进行图像变换的函数。
- QImage继承自QPaintDevice,可以使用QPainter直接绘制到图像上。
- Qt提供了QImage、QPixmap、QBitmap和QPicture四种处理图像数据的类。
- QImage类主要用于I/O和直接逐像素访问、操作;
- QPixmap主要用于在屏幕中显示图像;
- QBitmap只是一个继承QPixmap的便捷类,确保深度为1bit;
- QPicture是一个可以记录和响应QPainter类命令的画图设备。
Chapter3 QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)
原文链接:https://blog.csdn.net/weixin_43294620/article/details/122419099
QImage类(QImage类型转换、QImage类函数及QImage像素操作)
打开Qt帮助文档,会看到有关于QImage的描述如下:The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device。即QImage类是设备无关的图像,可以进行像素级操作,也可以被用作绘图设备,因为QImage继承于QPaintDevice。
Format:
打开enum QImage::Format,会看到如下信息:
Chapter4 Qt QImag图像保存、格式转换
原文链接:https://blog.csdn.net/m0_60259116/article/details/127754921
图像保存
bool QImage::save(const QString &fileName, const char *format = Q_NULLPTR, int quality = -1) const
保存格式选择
参数format选择保存的格式,支持格式如下:
BMP(Windows Bitmap)
GIF(Graphic Interchange Format (optional))
JPG(Joint Photographic Experts Group)
JPEG(Joint Photographic Experts Group)
PNG(Portable Network Graphics)
PBM(Portable Bitmap)
PGM(Portable Graymap)
PPM(Portable Pixmap)
XBM(X11 Bitmap)
XPM(X11 Pixmap)
保存质量设置
quality必须在0到100或-1范围内。
指定0来获得小的压缩文件,100用于大的未压缩文件,和-1(默认)使用默认设置。
1 GV_QImage.save(“ImageSavePath”+“.BMP”,“BMP”,100);
2 //1.pictrureName为图片文件的路径,比如:“/home/feng/IMG_0.jpg”,需要注意的是路径必须要有权限读写;
3 //2.“JPG"为图片的格式,注意不需要带”.";
4 //3.100指的是图片的质量因数,范围必须在0到100之内或-1,指定0以获取小型压缩文件,指定100表示大型未压缩文件,使用-1(默认值)使用默认设置。
图像格式转换
由 RGB 格式转换成 BGR 格式
QImage::rgbSwapped()
返回一个QImage,其中所有像素的红色和蓝色组件的值被交换,有效地将RGB图像转换为BGR图像。
QImage image(fileName);
QImage bgr = image.rgbSwapped();
将彩色图转换成 灰度图
使用QImage::convertToFormat()函数,
参数选择QImage::Format_Grayscale8(需要Qt5.5以上版本才支持)。
QImage image(fileName);
QImage gray = image.convertToFormat(QImage::Format_Grayscale8);
Chapter5 Qt中用QLabel显示图片
一、直接添加图片
1.参考Qt的帮助文档,可支持的类型,即可以直接读取并显示的格式有BMP、GIF、JPG、JPEG、PNG、TIFF、PBM、PGM、PPM、XBM、XPM。
2.显示图片步骤:
先打开一个图像;将图像文件加载进QImage对象中;再用QPixmap对象获得图像;最后用QLabel选择一个QPixmap图像对象显示。
这是要插入的图片:
QPixmap pixmap(":/images/abc.jpg");
pixmap.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
ui->label->setScaledContents(true);
ui->label->setPixmap(pixmap);
二、改变QLabel背景颜色
使用Qt样式表,qss语法直接修改
ui->label->setText(""); //清空字体
ui->label->setStyleSheet("QLabel#label11{background-color:rgb(200,101,102);}"); //设置样式表
Chapter6 QLabel中设置背景图片的3种方法
// [1] 图片不重复,可自由缩放
ui->label->setStyleSheet("QLabel{"
"border-image:url(:/images/bd.png) 4 4 4 4 stretch stretch;"
"}");
// [2] 图片不重复,大小固定
ui->label_2->setStyleSheet("QLabel{"
"background-image:url(:/images/bd.png);"
"background-position:top right;"
"background-origin:content;"
"background-repeat:none;"
"}");
// [3] 图片不重复,可设置缩放比例,不可动态缩放
QImage* img = new QImage;
img->load(QString(":/images/bd.png"));
QImage scaledimg;
scaledimg = img->scaled(ui->label_3->width(),ui->label_3->height(),Qt::KeepAspectRatio);
ui->label_3->setPixmap(QPixmap::fromImage(scaledimg));
Chapter7 QImage与QPixmap区别
原因
关于这个话题,我其实本人刚开始在windows下进行Qt开发时,并没有太在意?当突然被问到具体区别时,我突然就懵了。特意整理??
参考网址
https://www.cnblogs.com/s_agapo/archive/2012/03/14/2395603.html
https://blog.csdn.net/ailinty/article/details/8964431
https://blog.csdn.net/qq_18941425/article/details/79917185
区别:
具体四个区别请参考如上网址。
一、不同平台,依赖、存储不同
QPixmap依赖于硬件,QImage不依赖于硬件。
在X11, Mac 以及 Symbian平台上。
QImage: 因为它是存储在客户端,往QImage上绘图比较快,但显示它则比较慢。QPixmap: 具体实现是依赖于系统的,它是存储在服务器端,往QPixmap上绘图比较慢,但显示它则比较快。但在Windows平台上则是是一样的,因为它们都存储在客户端,并不使用任何的GDI资源,可能看起来并没有多大区别。
目前的Qt会把QPixmap都存储在graphics memory中,这明显是依赖硬件的。因此我们对QPixmap的使用需要格外注意。
那么Qt为什么要这么做呢?很简单,设计之初QPixmap就是用来加速显示的,例如我们在paint的时候用QPixmap就会比用其他类的效果好许多。
二、用处分工不同
QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的。
当图片小的情况下,直接用QPixmap进行加载,画图时无所谓,当图片大的时候如果直接用QPixmap进行加载,会占很大的内存,一般一张几十K的图片,用QPixmap加载进来会放大很多倍,所以一般图片大的情况下,用QImage进行加载,然后转乘QPixmap用户绘制。QPixmap绘制效果是最好的。
总结
对于显示小图片时,可以用QPixmap进行加载,绘画图片。当绘画大图片时候,此时最好实现QImage进行加载,因为QImage本身主要是为图像I/O、图片访问和像素修改而设计的,它可以实现对图片旋转、缩放等。然后通过QPixmap实现绘图。
Chapter8 QPixmap与QImage区别
前言
Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap 和 QPicture。 QImage 是为 I/O 和直接像素访问和操作而设计和优化的,而 QPixmap 是为在屏幕上显示图像而设计和优化的。 QBitmap只是一个继承QPixmap的便利类,保证深度为1。如果QPixmap对象是位图,isQBitmap()函数返回true,否则返回false。最后,QPicture 类是一个绘制设备,用于记录和重放 QPainter 命令
QPixmap & QImage
1、QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的
2、QPixmap依赖于所在的平台的绘图引擎,故例如反锯齿等一些效果在不同的平台上可能会有不同的显示效果,QImage使用Qt自身的绘图引擎,可在不同平台上具有相同的显示效果。
3、目前的Qt会把QPixmap都存储在graphics memory中,QImage是存储在客户端的,是独立于硬件的。在 X11, Mac 以及 Symbian平台上,QPixmap 是存储在服务器端,而QImage则是存储在客户端,在Windows平台上,QPixmap和QImage都是存储在客户端,并不使用任何的GDI资源。
4、由于QImage是独立于硬件的,也是一种QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在GUI线程中处理,使用这一方式可以很大幅度提高UI响应速度。
5、QImage 类用于加载图像文件,可选地操作图像数据,然后将 QImage 对象转换为 QPixmap 以显示在屏幕上。或者,如果不需要任何操作,可以将图像文件直接加载到 QPixmap 中。
6、QPixmap使用底层平台的绘制系统进行绘制,无法提供像素级别的操作,而QImage则是使用独立于硬件的绘制系统,实际上是自己绘制自己,因此提供了像素级别的操作,并且能够在不同系统之上提供一个一致的显示形式。
可以把QImage想象成一个RGB颜色的二维数组,记录了每一像素的颜色。
QBitmap
QBitmap继承自QPixmap,因此具有QPixmap的所有特性。QBitmap的色深始终为1. 色深这个概念来自计算机图形学,是指用于表现颜色的二进制的位数。我们知道,计算机里面的数据都是使用二进制表示的。为了表示一种颜色,我们也会使用二进制。比如我们要表示8种颜色,需要用3个二进制位,这时我们就说色深是3. 因此,所谓色深为1,也就是使用1个二进制位表示颜色。1个位只有两种状态:0和1,因此它所表示的颜色就有两种,黑和白。所以说,QBitmap实际上是只有黑白两色的图像数据。
由于QBitmap色深小,因此只占用很少的存储空间,所以适合做光标文件和笔刷。
QPicture
QPicture则是一个绘图装置,用于记录和重播Qpainter的绘图指令。
这是一个可以记录和重现QPainter命令的绘图设备。 QPicture将QPainter的命令序列化到一个IO设备,保存为一个平台独立的文件格式。这种格式有时候会是“元文件(meta- files)”。Qt的这种格式是二进制的,不同于某些本地的元文件,Qt的pictures文件没有内容上的限制,只要是能够被QPainter绘制的元素,不论是字体还是pixmap,或者是变换,都可以保存进一个picture中。
QPicture是平台无关的,因此它可以使用在多种设备之上,比如svg、pdf、ps、打印机或者屏幕。回忆下我们这里所说的QPaintDevice,实际上是说可以有QPainter绘制的对象。QPicture使用系统的分辨率,并且可以调整 QPainter来消除不同设备之间的显示差异。
·使用begin()方法在QPicture上进行绘图,使用end()结束绘图,使用save()保存至档案
QPainter painter;
painter.begin(&picture); // paint in picture
painter.drawEllipse(10,20, 80,70); // draw an ellipse
painter.end(); // painting done
picture.save("drawing.pic"); // save picture
需重播绘图指令的话,新建一个QPicture对象,使用load()重新载入保存的档案,然后再在指定的绘图设备QDevice上绘制QPicture:
QPicture picture;
picture.load("drawing.pic"); // load picture
QPainter painter;
painter.begin(&picture); // paint in myImage
painter.drawPicture(0, 0, picture); // draw the picture at (0,0)
painter.end(); // painting done