Qt QPainter CompositionMode解读及图片透明度设置

前言

Qt的QPainter十分强大,设置不同的组合模式,可以得到迥然不同的结果,比如调节图片的透明度等,因此是否有必要弄清除QPainter的组合模式代表的意义。

研究相关

  • Source指的是绘制的输入,Destination指的是目的绘制区域本来存在的像素。
  • 本文使用"Compositon Modes"程序对QPainter的组合模式进行解读,其中花是绘制区域原来存在的像素,椭圆是绘制的输入,Circle color是椭圆的的RGB通道数值,circle alpha是椭圆的透明通道数值。

QPainter::CompositionMode

QPainter::CompositionMode_SourceOver

  • Qt帮组文档描述:This is the default mode. The alpha of the source is used to blend the pixel on top of the destination.
  • SourceOver是默认的绘制模式,绘制结果 = 绘制输入*ratio_source + 目的区域原来像素 * ratio_destination。ratio_source和ratio_destination取决于绘制输入的alpha通道值与绘制区域的alpha通道数值的比值(大部分取决于绘制区域的alpha数值,关系不是线性)。
    • 测试数据
目的区域像素 输入像素 结果
(255, 255, 255, 10) (0, 0, 0, 100) (14, 14, 14, 102)
(255, 255, 255, 10) (0, 0, 0, 200) (3,3,3,202)
(255, 255, 255, 10) (0, 0, 0, 255) (0, 0, 0, 255)
(255, 255, 255, 255) (100, 0, 0, 200) (133, 55, 55, 255)
(255, 255, 255, 0) (0, 0, 0, 200) (0, 0, 0, 200)

SourceOver在这里插入图片描述

QPainter::CompositionMode_Source

  • Qt帮组文档描述:The output is the source pixel. (This means a basic copy operation and is identical to SourceOver when the source pixel is opaque).
  • Source模式:绘制结果 = 绘制输入,目的绘制区域原来的像素被完全覆盖。
  • 当绘制输入的Alpha通道为255(不透明时),Source和SourceOver模式的表现相同,因为SourceOver模式中ratio_source = 1,ratio_destination = 0;
    在这里插入图片描述
    在这里插入图片描述

QPainter::CompositionMode_DestinationIn

  • Qt帮组文档描述:The output is the destination, where the alpha is reduced by that of the source. This mode is the inverse of CompositionMode_SourceIn.
  • DestinationIn模式,最后的绘制结果为原绘制区域图像,但是其alpha通道数值会受到输入的影响。
  • 绘制结果 = 区域原像素(除Alpha通道外) + 区域原像素(Alpha通道)* 绘制输入(Alpha通道)/ 255,绘制输入(除Alpha通道)的值被丢弃,因此该模式一般仅用于设置绘制区域的透明度。
    • 绘制结果通过代码测试出来
      • x = 200; 输出为1325400063(4EFFFFFF),Alpha通道值为78(0x4E),而100 * (200/255) = 78.4313;
      • x = 100;输出为671088639(27FFFFFF),Alpha通道为39(0x27),而100 * (100/255) = 39.6825
    • 测试代码
      QImage temp(QSize(100, 100), QImage::Format_ARGB32);
      temp.fill(QColor(255, 255, 255, 100));
      QPainter painter(&temp);
      painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
      painter.fillRect(temp.rect(), QColor(0, 0, 0, x));
      painter.end();
      qDebug() << temp.pixel(50, 50);
      

在这里插入图片描述在这里插入图片描述在这里插入图片描述

调节图片透明度

/* 最后生成的img_res是img图片的透明复制 */

QPixmap temp(this->img.size());
temp.fill(Qt::transparent);

QPainter p1(&temp);
// CompositionMode_Source将图片绘制进去
p1.setCompositionMode(QPainter::CompositionMode_Source);
p1.drawPixmap(0, 0, this->img);
// CompositionMode_DestinationIn设置图片的透明度
p1.setCompositionMode(QPainter::CompositionMode_DestinationIn);
// 根据QColor中第四个参数设置透明度,此处position的取值范围是0~255
p1.fillRect(temp.rect(), QColor(0, 0, 0, this->transparency * 255/100));
p1.end();

this->img_res = temp.copy();

QPainter::CompositionMode_DestinationOut

  • Qt帮组文档描述:The output is the destination, where the alpha is reduced by the inverse of the source. This mode is the inverse of CompositionMode_SourceOut.
  • DestinationOut模式,最后的绘制结果为原绘制区域图像,但是其alpha透明通道数值会受到输入alpha透明通道取反值的影响。
  • 绘制结果 = 区域原像素(除Alpha通道外) + 区域原像素(Alpha通道)* (255 - 绘制输入(Alpha通道))/ 255,绘制输入(除Alpha通道)的值被丢弃,因此该模式一般仅用于设置绘制区域的透明度。
目的区域像素 输入像素 结果
(255, 255, 255, 200) (255, 255, 255, 127) (255, 255, 255, 100)
(255, 255, 255, 100) (255, 255, 255, 127) (255, 255, 255, 50)
(255, 255, 255, 50) (255, 255, 255, 127) (255, 255, 255, 25)
(255, 255, 255, 25) (255, 255, 255, 127) (255, 255, 255, 13)
(255, 255, 255, 13) (255, 255, 255, 127) (255, 255, 255, 7)
(255, 255, 255, 7) (255, 255, 255, 127) (255, 255, 255, 4)
(255, 255, 255, 4) (255, 255, 255, 127) (255, 255, 255, 2)
(255, 255, 255, 2) (255, 255, 255, 127) (255, 255, 255, 1)
(255, 255, 255, 1) (255, 255, 255, 127) (255, 255, 255, 1)
  • 从测试数据中不难看出,该模式可以用作画板的橡皮檫,多次擦除后,最后残留的像素必为(x, x, x, 1),显示出来的结果近似与空白,而又不会破坏画板。
    • 需要注意的是,橡皮檫的透明通道最大为127,否则将穿透画板(最后的像素透明通道为0),因为大于127,则有(255 - 127)/255 < 0.5,多次擦除后透明通道将为0。

写在最后

  • 目前只列举了常见的三种CompositionMode,这三种模式可以用于调节图片的透明度。后续将继续补充。
  • 20200328更新:加入CompositionMode_DestinationOut模式的解读。
发布了22 篇原创文章 · 获赞 8 · 访问量 1万+
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览