用Qt(C++)实现如苹果般的亮屏效果?

苹果的亮屏效果可能有很多人没注意到,和其他大部分手机或电脑不同的是,苹果的亮屏特效不是简单的亮度变化,而是一个渐亮的过程。详细来说就是,图片中较亮的部分先显示出来,而后渐变的显示较暗的地方,最后整个图片完全显示。

想要实现此效果,首先需要了解到的Qt函数:

//该函数用于设置图片中(x,y)点的rgb值
void QImage::setPixel(int x, int y, uint index_or_rgb);

思路

可以很明显的看出,点亮和关屏都不是一瞬间完成的,所以,我们首先需要一个计时器来控制该过程。而后我们需要确定该算法的索引,也就是说,假设这个过程需要100帧,那么我们肯定需要一个变量用于记录这个过程执行的进度。再根据进度,计算出当前帧的所有像素点应显示的内容,从而得到这一帧的图片。

如果是普通的亮度计算的话,很简单,只需要每一个像素的RGB值分别和亮度系数相乘即可。亮度系数如果在0-1区间内的话,那么对应的就是从完全黑的图片显示出图片本身的一个过程。

例如:

下边这个RGB颜色值为深绿色:

(15,40,30)

将RGB三个数字乘以1.5,就会变成下边这个颜色:

(22.5,60,45)

这就是亮度调节的基本原理。

实现

跟着思路,写下如下代码:

#include “mainwindow.h”
#include “ui_mainwindow.h”
#include <QRgb>
#include <QImage>
#include <QTimer>
#define PASS 0.3;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
p.load(“:/b.jpg”);
double size=0.4; //图片缩放系数
p=p.scaled(p.width()*size,p.height()*size);
ui->label->setPixmap(QPixmap::fromImage(p));
speed=0;
timer=new QTimer;
timer->setInterval(1);
i=0;
connect(timer,&QTimer::timeout,[=](){
i+=speed;
MainWindow::update(i);
if(i>100 || i<0){
i=0;
timer->stop();
}
});
on_pushButton_clicked();
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::update(int position) //参数为0-100,若从0开始,则逐步变亮,若从100开始,则逐步变暗
{
QImage t(p);
double bright=double(position)/100; //亮度系数
bright=(bright>1)?1:bright;
bright=(bright<0)?0:bright;

double flag=-bright+1; //渐亮需要的阈值
setWindowTitle(“亮度:” + QString::number(bright)+
“阈值:”+ QString::number(flag));
for(int x=0;x<p.width();x++){
for (int y=0;y<p.height();y++) {
QColor c(p.pixel(x,y));
double b=double(c.red()+c.green()+c.blue())/765; //计算当前像素的亮度
if(b>flag){ //判断亮度与阈值的大小关系
//若亮度大于阈值,将该像素乘以亮度系数
c.setRgb((int(c.red()*bright)>255)?255:int(c.red()*bright),
(int(c.green()*bright)>255)?255:int(c.green()*bright),
(int(c.blue()*bright)>255)?255:int(c.blue()*bright));
}else {
//若亮度小于阈值,则显示黑色像素,这部分会导致出现问题,后边会替换。
c.setRgb(0,0,0);
}
t.setPixel(x,y,c.rgb());//将像素写入临时变量
}
}
ui->label->setPixmap(QPixmap::fromImage(t));//将计算好的一帧显示在label上
}

void MainWindow::on_pushButton_clicked()
{
//灭
i=100;
speed=-3;
timer->start();
}

void MainWindow::on_pushButton_2_clicked()
{
//亮
i=0;
speed=3;
timer->start();
}

效果虽然大体实现了,但是还是很差劲的,渐亮的边缘过于生硬

所以,将像素置为黑色部分的代码替换为以下代码:

else {
//c.setRgb(0,0,0);
double a=1.0-(flag-b)*10; //获取加权亮度系数,亮度越大,系数越大,亮度越小,系数越小,最小到0
a=(a<0)?0:a;
c.setRgb((int(c.red()*bright*a)>255)?255:int(c.red()*bright*a),
(int(c.green()*bright*a)>255)?255:int(c.green()*bright*a),
(int(c.blue()*bright*a)>255)?255:int(c.blue()*bright*a));
}

————下载必看————

1、资源通过互联网渠道公开获取,仅供阅读测试,请在下载后24小时内删除,谢谢合作!
2、若版权方认为本站侵权,请联系发邮件至(rsstime@qq.com)处理。
3、本站解压密码统一为:yudouyudou

时光屋 » 用Qt(C++)实现如苹果般的亮屏效果?

发表评论

至臻视听_发烧收藏

会员介绍 常见问题