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

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

那么,Qt该如何实现类似效果?

先看最终效果:

图中是一束灯光,点亮时光束中间较亮的部位显现出来,再带动其他部位显现,这个效果暂且成为“渐亮”。

用到

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

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

思路

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

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

例如:

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

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

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

所以,要实现渐亮,就要先显现出亮度大于阈值的像素,随着时间推移,阈值越来越大,显示的像素越来越多。

那么,如何获取某像素的亮度值呢?

当RGB三个值均为255时,亮度最大,显白色,当三个值均为0时,亮度最小,显黑色。那么我们可以获取RGB三值的平均数,将其与255相除,规定其为亮度值,也就是说:亮度值=(red+green+blue)/3/255,化简后得:亮度值=(red+green+blue)/765

到此,基本的原理就搞清楚了,但是这里仍然还有一个问题,等我们先实现后再说明。

实现

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

#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));
}

修改后的效果:

很明显,柔和了许多。

到此为止基本上效果已经实现了,当然,肯定没有苹果那么丝滑,只是形似。

用Qt(C++)实现如苹果般的亮屏效果的更多相关文章

  1. MSM8909的触摸屏驱动导致的熄屏后重新亮屏速度慢的原因!【转】

    转自:https://blog.csdn.net/kk20000/article/details/83041081 使用的汇顶的触摸驱动的时候会重新亮屏速度慢3秒,而在使用另外一个敦泰触摸驱动的时候没 ...

  2. Android让手机主动亮屏的代码

    我们在做电子阅读器的时候可能会要求屏幕保持常亮,不希望它熄灭.它的原理也是利用系统服务,来操纵底层设备. 一.系统服务——PowerManager PowerManager.java就是管理我们电源方 ...

  3. Android Notification实现推送消息过程中接受到消息端有声音及震动及亮屏提示

    在Android Notification状态栏通知一文中,简单实现了消息的推送效果,这里就接着上文说一下,当用户接受到消息时的提示效果 // 5-增加震动及声音及亮屏 notification.de ...

  4. iOS亮屏解锁命令【iOS自动化测试】--使用ssh

    前提:iOS越狱手机一个 越狱方法:使用pp助手, 爱思助手等 1.从Cydia安装以下软件: AppSync for iOSx(可安装破解软件).afc2add补丁(可访问整个iOS设备的系统文件) ...

  5. python3:判断手机的亮屏状态

    在用python对手机做一些自动化操作时,常常会判断手机的亮屏状态,知晓手机的亮屏状态后才好做进一步的动作,如给屏幕解锁等.  用于了解手机的亮屏情况,有一个adb命令可用: adb shell du ...

  6. Android 动态注册 亮屏、息屏广播

    /***************************************************************************** * Android 动态注册 亮屏.息屏广 ...

  7. Qt无边框窗体-模拟模态窗体抖动效果

    目录 一.概述 二.效果展示 三.功能实现 四.相关文章 原文链接:Qt无边框窗体-模拟模态窗体抖动效果 一.概述 用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来说也不错 ...

  8. 搭建Android+QT+OpenCV环境,实现“单色图片着色”效果

               OpenCV是我们大家非常熟悉的图像处理开源类库:在其新版本将原本在Contrib分库中的DNN模块融合到了主库中,并且更新了相应文档.这样我们就能够非常方便地利用OpenCV实 ...

  9. 通过adb操作安卓亮屏、设置背光亮度、解锁、打开app

    亮屏 adb shell inputkeyevent 26 keyevent 26表示点击power Android adb 点亮和关闭屏幕的命令 # kernel休眠 echo mem > / ...

随机推荐

  1. DRF 三大认证之身份认证

    目录 路由组件补充 三大认证 一.身份认证 1.如何进行身份认证 2.jwt认证规则原理 3.jwt的组成 4.jwt的使用方法 4.1 签发算法 4.2 校验算法 4.3 刷新算法 二.权限认证 三 ...

  2. spring boot自定义类配置绑定在配置文件中自动提示

    在spring boot的日常使用中,我们可能需要使用配置绑定的方式动态配置自定义类的成员变量. 这个时候,我们在配置文件中配置spring默认已有的配置时,只需要输入部分关键字即可自动提示,如下图: ...

  3. Kafka集群消息积压问题及处理策略

    通常情况下,企业中会采取轮询或者随机的方式,通过Kafka的producer向Kafka集群生产数据,来尽可能保证Kafka分区之间的数据是均匀分布的. 在分区数据均匀分布的前提下,如果我们针对要处理 ...

  4. zabbix 面板graph图上没有数据显示

    1. 问题: zabbix_server日志出现大量如下错误: query failed: [1526] Table has no partition for value 1507509984 2. ...

  5. SpringMVC-01 什么是SpringMVC

    SpringMVC-01 什么是SpringMVC 回顾MVC 1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑 ...

  6. 【RocketMQ源码分析】深入消息存储(1)

    最近在学习RocketMQ相关的东西,在学习之余沉淀几篇笔记. RocketMQ有很多值得关注的设计点,消息发送.消息消费.路由中心NameServer.消息过滤.消息存储.主从同步.事务消息等等. ...

  7. 文件包含-phpinfo()

    我也是听朋友说有这个姿势的,github有集成好的环境 先讲一下利用phpinfo上传文件,然后在文件包含的原理: 在给PHP发送POST数据包时,如果数据包里包含文件区块,无论访问的代码中是否有处理 ...

  8. python学习总结篇(2)——函数

    如其他语言一样,除了基本知识外,另外一个重要的板块就是函数了,python中也有函数. 在python中,函数的定义方式为: def   函数名( ): 下面通过几个简单的例子,看看python中的函 ...

  9. cpu缓存和volatile

    目录 CPU缓存的由来 CPU缓存的概念 CPU缓存的意义 缓存一致性协议-MESI协议 Store Buffers Store Forwarding Memory Barriers Invalida ...

  10. beego 框架用的页面样式模板

    https://themequarry.com/category/free 页面样式