Qt 2D绘图(6):QPixmap类及蒙版原理

Qt 2D绘图(6):QPixmap类及蒙版原理

本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

若对C++语法不熟悉,建议参阅《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

12.13.4 QPixmap类中的成员函数

QPixmap默认支持的文件格式如表12-23
在这里插入图片描述

1、构造函数
在这里插入图片描述
2、像素图的加载和存储
在这里插入图片描述
在这里插入图片描述

示例12.29:把像素图保存到文件与绘制到QWidget部件的区别

void paintEvent(QPaintEvent *e){
    		QPainter pr;
    		QPixmap pm;
		pm.load("F:/1i.png");
    		qDebug()<<pm.cacheKey();   			//1、验证改变像素图时cacheKey()的值会被改变。
	//在pm绘制一直线
    		pr.begin(&pm);		pr.drawLine(11,11,44,111);		pr.end();
    		qDebug()<<pm.cacheKey();   			 //此处输出的值与在1处输出的值不相同。
pr.begin(this);		
pr.drawPixmap(11,11,333,222,pm); 	//把pm绘制到QWidget部件的矩形(11,11,444,333)上。
    		pm.save("F:/zzz.png");	   			//保存图像
pr.end();}   

运行结果及说明见图12-68
在这里插入图片描述

3、像素图的基本信息
在这里插入图片描述

void paintEvent(QPaintEvent *e){
   			QPainter pr;
            	QPixmap pm;
        		pm.load("F:/2.jpg");		//假设图片大小为300*300(这个大小是不会变的)
    			pm.setDevicePixelRatio(2);	//设置设备像素比为2。
   			pr.begin(&pm);			//在pm上绘制图形
    			pr.drawLine(0,100,100,100);	//此直线绘制到pm上时,将变为(0,200,200,200)
    			pr.end();
pr.begin(this);			//在当前设备上绘制图形
pr.drawPixmap(11,11,pm); 	//把pm显示到当前设备上,图片2.jpg将被显示为
//150*150的大小,且绘制的直线显示为(0,100,100,100)
pr.end();
pm.save("F:/2222.jpg");	}	//保存图像,图像222.jpg的大小仍为300*300,但在该图像上
//绘制的直线为(0,200,200,200),可在F盘找到该文件进行查看

4、像素图的复制、填充、替换
在这里插入图片描述

5、像素图的缩放与滚动
在这里插入图片描述

示例12.30:像素图的缩放(结果见图12-69)
void paintEvent(QPaintEvent *e){
QPainter pr;    QPixmap pm(120,55);    QFont f;    f.setPointSize(33);
//在pm上绘制文字
    pr.begin(&pm);    pr.setFont(f);    pr.drawText(0,33,"ABCDF");    pr.end();
pr.begin(this);    pr.drawPixmap(11,11,pm);   //绘制原始文字
//不保留纵横比
QPixmap pm1=pm.scaled(100,100,Qt::IgnoreAspectRatio);    pr.drawPixmap(133,11,pm1);
//在给定矩形(100,100)内,图像尺寸在保持纵横比的情形下,图像保持最大矩形。
QPixmap pm2=pm.scaled(100,100,Qt::KeepAspectRatio);    pr.drawPixmap(255,11,pm2);
//在给定矩形外,图像尺寸在保持纵横比的情形下,图像外部尺寸保持尽可能小的矩形。
    QPixmap pm3=pm.scaled(100,100,Qt::KeepAspectRatioByExpanding);	pr.drawPixmap(377,11,pm3);
pr.end();}

在这里插入图片描述

在这里插入图片描述

示例12.31:图像滚动原理

void paintEvent(QPaintEvent *e){
    		QPainter pr(this);    		QPixmap pm("F:/111.png");	QRegion g;  
QRect r(33,33,111,111);		pm.scroll(33,33,r,&g);		pr.drawPixmap(11,11,pm);
//输出:QRegion(size=2,bounds=(33,33 111x111)-[(33,33 111x33),(33,66 33x78)])
qDebug()<<g;} 

在这里插入图片描述

6、像素图变换
在这里插入图片描述
7、QPixmap与QImage之间的转换
在这里插入图片描述

示例12.32:convertFromImage()函数的使用(效果见图12-71)

void paintEvent(QPaintEvent *e){
   		QPainter pr(this);   QPixmap pm("F:/1i.png");   QImage pi("F:/1m.png");
   		pr.drawPixmap(11,11,pm);   pr.drawImage(77,11,pi);
   		pm.convertFromImage(pi);   pr.drawPixmap(288,11,pm);}

在这里插入图片描述

8、蒙版(mask)
蒙版的概念:
在绘图软件中,蒙版类似于蒙在原始图片上的一块玻璃(即蒙版),然后我们再在这块玻璃上使用其他工具对图片进行修改,这样就不会破坏原始图片,而又能看到图片修改后的效果。
蒙版通常是黑白色的,通常通过改变蒙版(玻璃)的灰度可改变蒙版的透明度,从而可使原始图片变为可见、不可见、透明三种效果,也就是说蒙版本身只能改变透明度,并不能改变原始图像的色彩或其他性质(这些性质的改变需借助其他工具)。
蒙版很少有彩色蒙版,几乎都是黑白色的(即只能通过灰度改变透明度),虽然可使用蒙版蒙住原始图的某个通道,但蒙版本身仍是黑白色的。比如使用蒙版蒙住红色通道,则通过改变蒙版本身的透明度,可使原始图的红色变为可见、不可见或透明,但蒙版本身并不是彩色的。
Qt通常使用QBitmap类来保存蒙版,QBitmap类是一个只有1位深度的图像,因此Qt的蒙版只能在可见和不可见之间变换,不能实现透明度的效果。
注意:被蒙板黑色部分遮挡的像素会被显示,被白色部分遮档的像素不会被显示。白色:显示、不透明。黑色:隐藏、透明。
下面为QPixmap类中与蒙版有关的函数
在这里插入图片描述

示例12.33:createHeuristicMask()函数创建的蒙版(效果见图12-72)

void paintEvent(QPaintEvent *e){
QPainter pr(this);   QPixmap pm("F:/1z.png");   QPixmap pm1("F:/1z.png");
//创建两个蒙版
   QBitmap pt=pm.createHeuristicMask(true);   QBitmap pt1=pm1.createHeuristicMask(false);
   pr.drawPixmap(11,11,pm);   //绘制原始图片
//蒙版pt的效果
   pm.setMask(pt);   pr.drawPixmap(222,11,pm);   pr.drawPixmap(222,222,pt);
//蒙版pt1的效果
   pm1.setMask(pt1);   pr.drawPixmap(444,11,pm1);   pr.drawPixmap(444,222,pt1);}

在这里插入图片描述

示例12.34:createMaskFromColor()函数创建的蒙版(效果见图12-73)

void paintEvent(QPaintEvent *e){
   QPainter pr(this);   QPixmap pm("F:/1z.png");   QPixmap pm1("F:/1z.png");
//创建两个蒙版
   QBitmap pt2=pm.createMaskFromColor(QColor(255,0,0),Qt::MaskInColor);
   QBitmap pt3=pm.createMaskFromColor(QColor(255,0,0),Qt::MaskOutColor);
   pr.drawPixmap(11,11,pm);	//绘制原始图片
//蒙版pt2的效果
pm.setMask(pt2);   pr.drawPixmap(222,11,pm);   pr.drawPixmap(222,222,pt2);
//蒙版pt3的效果
   pm1.setMask(pt3);   pr.drawPixmap(444,11,pm1);   pr.drawPixmap(444,222,pt3);}

在这里插入图片描述

示例12.35:setMask()函数会合并蒙版

void paintEvent(QPaintEvent *e){
   QPainter pr(this);   QPixmap pm("F:/1z.png");
   QBitmap pt=pm.createHeuristicMask(true);
   QBitmap pt2=pm.createMaskFromColor(QColor(0,255,0),Qt::MaskInColor);
   pr.drawPixmap(11,11,pm);   			//绘制原始图像。
   pm.setMask(pt);   pm.setMask(pt2);   	//同一像素图上设置两个蒙板,这两个蒙版会合并。
   pr.drawPixmap(222,11,pm);   pr.drawPixmap(444,11,pt);   pr.drawPixmap(666,11,pt2);}

运行结果及说明(见图12-74)
在这里插入图片描述

12.13.5 QBitmap类(位图)中的成员函数

QBitmap类继承自QPixmap,该类描述的是1位深度(单色)的像素图,即只有两种色的像素图。该类主要用于创建自定义的QCursor(光标)对象、QRegion对象及设置图像的蒙版等。
若把深度大于1的像素图分配给QBitmap,则QBitmap将自动抖动。
使用Qt::color0将位图的位设置为0,使用Qt::color1把位图的位设置为1。其中0表示背景(透明像素),1表示前景(不透明像素)。注意:使用Qt::black(黑色)和Qt::white(白色)没有意义。位图的效果见图12-75。

在这里插入图片描述

QBitmap类中的函数如下

1)、QBitmap();		//构造函数
QBitmap(int width, int height);
QBitmap(const QSize &size);
QBitmap(const QPixmap &pixmap);   //使用pixmap构造一个位图
QBitmap(const QString &fileName, const char *format = Q_NULLPTR);
QBitmap(const QBitmap &other);
2)、void clear();    				//清除位图,即把所有位设置为Qt::color0。
3)、void swap(QBitmap &other);   	//把该位图与other交换。
4)、QBitmap transformed(const QTransform &matrix) const;  
	使用变换矩阵matrix变换位图,并返回变换后的副本。
5)、static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);  //静态的
	把图像image转换为位图,并返回其副本。枚举Qt::ImageConversionFlag见表12-21。
6)、static QBitmap fromData(const QSize &size, const uchar *bits, 
QImage::Format monoFormat = QImage::Format_MonoLSB);  //静态的
	构造一个大小为size的位图,并把内容设置为bits,位图数据必须是字节对齐的,并需按monoFormat指定的位顺序提供,单色图格式必须是QImage::Format_Mono或QImage::Format_MonoLSB。

本文作者:黄邦勇帅(原名:黄勇)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hyongilfmmm/article/details/83234890