Qt 图像合成模式(二): SourceIn_Demo

本文介绍如何使用Qt的图像合成模式Srcln来实现图片的替换与合成效果,包括创建画框、剪切图画及生成阴影等技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Qt 图像合成模式(二): SourceIn_Demo

​ 这个例子中的思路和图片素材都是采用《Java 极富客户端》的例子。Qt普及性的资料实在是不够,只有掌握了其他部分知识的学习才能用好Qt,对于C++来说这无可厚非,但是对于集成式的Qt框架,解决方案都已经固定了,相关的资料应该可以更加的细致。相对来说 Java中的基础性的知识还是比较多的,知识由浅入深,有原理有代码有资源,比较容易学习,Java的官网文档和教程做得还真是好。Qt的给出的教程就是一个大纲,里面涉及的知识及其原理只提到了相应的名词。书归正传,还是来看看本次的主题吧。

​ Srcln是一个有用的的合成。无论什么时候想要替换一个现有的图像的内容时,都可以使用它。下图演示了一个在屏幕上描绘一个简单的盾牌,并用渐变的蓝色 填充它的应用程序。
​ 如果想要绘制一个相似的盾牌,但是在内部用一个图片而不是用渐变的颜色,那将会怎 样?通过在图形区域上设置Srcln透明合成可以容易地做到这一点:

​ 按照Srcln规则,只显示 源图像 位于目标图像内部的那部分。

​ 可以使用这个技术为图片创建画框、剪切图画或图像,甚至还可以生成阴影。如果在原图 的上方填充一个黑色的矩形,就会获得一个阴影。在这个阴影的偏移位置和顶部再次绘制这个原图,将得到想要的效果。

Widget.h

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void resizeEvent(QResizeEvent *event) override;
    void paintEvent(QPaintEvent *event) override;
    QImage *picture;
    QImage *landscape;
    QCheckBox *shadow;
};

Widget.cpp

#include "Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    resize(350,250);
    picture     = new QImage("picture.png");
    landscape   = new QImage("landscape.jpg");

    shadow = new QCheckBox("draw shadow",this);
    shadow->move(10,height()-30);

    //QWiget 默认没有布局管理器
    qDebug() << layout();

    // 事件关联
    connect(shadow,&QCheckBox::stateChanged,[&](){
        update();
    });
}

Widget::~Widget()
{
    delete picture;
    delete landscape;
}

void Widget::resizeEvent(QResizeEvent */*event*/)
{
    //绝对定位,需要刷新位置
    shadow->move(10,height()-30);
}

void Widget::paintEvent(QPaintEvent */*event*/)
{
    QPainter painter;
    QImage *shadowImg=0;
    QImage res(width(),height(),QImage::Format_ARGB32_Premultiplied);
    //填空image数据
    res.fill(0);

    int x = (width() - picture->width() )/2;
    int y = (height() - picture->height() )/2;

    //-----绘制阴影画布
    if(shadow->isChecked()){
        shadowImg = new QImage(width(),height(),QImage::Format_ARGB32_Premultiplied);
        //填空image数据
        shadowImg->fill(0);
        painter.begin(shadowImg);
        painter.drawImage( x+4,y+8, *picture);

        painter.setCompositionMode(QPainter::CompositionMode_SourceIn);

        painter.setBrush(Qt::black);
        //设置透明度,有点单独的alpha的意思。
        painter.setOpacity(0.75);
        painter.drawRect(0,0,width(),height());

        painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
        painter.drawImage( x,y, *picture);
        painter.end();
    }

    // QWidget本身格式不是QImage::Format_ARGB32_Premultiplied
    // 所以使用QImage当做一层画布
    //-----绘制背景画布
    painter.begin(&res);

    painter.drawImage( x,y, *picture);
    painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    painter.drawImage((width() - landscape->width() )/2,(height() - landscape->height() )/2,*landscape);

    painter.end();

    //-----绘制到控件上
    painter.begin(this);
    if(shadowImg) {
        painter.drawImage( 0,0,*shadowImg);
        delete shadowImg;
    }
    painter.drawImage( 0,0,res);
    painter.end();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值