0
点赞
收藏
分享

微信扫一扫

Qt之实现图片或按钮等控件的倒影效果


一.原理

倒影效果在轮播图中用得比较多,当然音乐频谱中也有用到。通常的做法是将原图垂直镜像,然后在原图下面绘制该镜像图
用Qt获取镜像图比较方便,调用QImage的mirrored方法就行,该方法有两个参数,分别可以控制水平或(和)垂直镜像
获取垂直镜像的代码如下所示

QImage img(":/icons/snow.png");
QImage mirriored = img.mirrored(false, true);

如果给按钮等控件绘制倒影,需要先获取按钮的图像,这一点用Qt也很好实现,如下所示

QPixmap pix(ui->pushButton->size());
ui->pushButton->render(&pix);

接着将pix做垂直镜像就行

QImage mirriored2 = pix.toImage().mirrored(false, true);

如果镜像图不做任何处理,最基础的倒影效果如下图所示

Qt之实现图片或按钮等控件的倒影效果_图像融合

 上图中的倒影效果比较生硬,就好比说大树在水中的倒影,并不是和岸上的书一毛一样,有种由近及远渐渐模糊的效果,因此需要给上图中的倒影加渐变,这就涉及到了图像融合(composition)
在Qt Creator中搜索composition,可以看到两个demo,有了这两个demo,还要什么自行车

Qt之实现图片或按钮等控件的倒影效果_图像融合_02


本文用到的融合模式是QPainter::CompositionMode_DestinationIn,关于该模式,Qt assistant中的解释是

The output is the destination, where the alpha is reduced by that of the source. 

可以简单的理解为混合后输出的是目标图像,且目标图像的透明度会随着原图像的透明度的减少而减少,举个例子

// 设置倒影渐变.
painter.begin(&mirriored);
QLinearGradient g(0, 0, 0, mirriored.height());
g.setColorAt(0, QColor(0, 0, 0, 255));
g.setColorAt(1.0, QColor(0, 0, 0, 0));
//设置图像合成模式.
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
painter.fillRect(mirriored.rect(),g);
painter.end();

上面代码中将镜像图作为目标图像,将黑色线性渐变作为原图像,融合以后,输出的是目标图像,但此时目标图像从上到下会越来越透明
实际上这的线性渐变可以是任意颜色,只要透明度是渐变的就行,因为在QPainter::CompositionMode_DestinationIn模式下,原图像只会影响目标图像的透明度

Qt之实现图片或按钮等控件的倒影效果_Qt_03

 二.实现

完整代码如下:

void QHReflection::paintEvent(QPaintEvent *event)
{
// 图片.---------------------------
QImage backgroundImg(width(), height()/2, QImage::Format_ARGB32_Premultiplied);
backgroundImg.fill(Qt::black);

QImage img(":/icons/snow.png");
QImage mirriored = img.mirrored(false, true);

// 绘制原图.
QPainter painter;
painter.begin(&backgroundImg);
painter.drawImage((width()-img.width())/2, 0, img);
painter.end();

// 设置倒影渐变.
painter.begin(&mirriored);
QLinearGradient g(0, 0, 0, mirriored.height());
g.setColorAt(0, QColor(0, 0, 0, 255));
g.setColorAt(1.0, QColor(0, 0, 0, 0));
// 设置图像合成模式.
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
painter.fillRect(mirriored.rect(),g);
painter.end();

// 绘制倒影.
painter.begin(&backgroundImg);
painter.drawImage((width()-img.width())/2, img.height(), mirriored);
painter.end();

// 将背景绘制到窗口中.
painter.begin(this);
painter.drawImage(0, 0, backgroundImg);
painter.end();

// 按钮.----------------------------
QPixmap pix(ui->pushButton->size());
ui->pushButton->render(&pix);
QImage mirriored2 = pix.toImage().mirrored(false, true);

QImage backgroundImg2(width(), height()/2, QImage::Format_ARGB32_Premultiplied);
backgroundImg2.fill(Qt::white);
// 设置倒影渐变.
painter.begin(&mirriored2);
QLinearGradient g2(0, 0, 0, mirriored2.height());
g2.setColorAt(0, QColor(255, 255, 255, 255));
g2.setColorAt(1.0, QColor(255, 255, 255, 0));
//设置图像合成模式.
painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
painter.fillRect(mirriored2.rect(),g2);
painter.end();

// 绘制倒影.
painter.begin(&backgroundImg2);
painter.drawImage(ui->pushButton->x(), ui->pushButton->y()+ui->pushButton->height()-height()/2, mirriored2);
painter.end();

// 将背景绘制到窗口中.
painter.begin(this);
painter.drawImage(0, height()/2, backgroundImg2);
painter.end();
}

举报

相关推荐

0 条评论