用Qt(C++)实现如苹果般的亮屏效果
用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++)实现如苹果般的亮屏效果的更多相关文章
- MSM8909的触摸屏驱动导致的熄屏后重新亮屏速度慢的原因!【转】
转自:https://blog.csdn.net/kk20000/article/details/83041081 使用的汇顶的触摸驱动的时候会重新亮屏速度慢3秒,而在使用另外一个敦泰触摸驱动的时候没 ...
- Android让手机主动亮屏的代码
我们在做电子阅读器的时候可能会要求屏幕保持常亮,不希望它熄灭.它的原理也是利用系统服务,来操纵底层设备. 一.系统服务——PowerManager PowerManager.java就是管理我们电源方 ...
- Android Notification实现推送消息过程中接受到消息端有声音及震动及亮屏提示
在Android Notification状态栏通知一文中,简单实现了消息的推送效果,这里就接着上文说一下,当用户接受到消息时的提示效果 // 5-增加震动及声音及亮屏 notification.de ...
- iOS亮屏解锁命令【iOS自动化测试】--使用ssh
前提:iOS越狱手机一个 越狱方法:使用pp助手, 爱思助手等 1.从Cydia安装以下软件: AppSync for iOSx(可安装破解软件).afc2add补丁(可访问整个iOS设备的系统文件) ...
- python3:判断手机的亮屏状态
在用python对手机做一些自动化操作时,常常会判断手机的亮屏状态,知晓手机的亮屏状态后才好做进一步的动作,如给屏幕解锁等. 用于了解手机的亮屏情况,有一个adb命令可用: adb shell du ...
- Android 动态注册 亮屏、息屏广播
/***************************************************************************** * Android 动态注册 亮屏.息屏广 ...
- Qt无边框窗体-模拟模态窗体抖动效果
目录 一.概述 二.效果展示 三.功能实现 四.相关文章 原文链接:Qt无边框窗体-模拟模态窗体抖动效果 一.概述 用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来说也不错 ...
- 搭建Android+QT+OpenCV环境,实现“单色图片着色”效果
OpenCV是我们大家非常熟悉的图像处理开源类库:在其新版本将原本在Contrib分库中的DNN模块融合到了主库中,并且更新了相应文档.这样我们就能够非常方便地利用OpenCV实 ...
- 通过adb操作安卓亮屏、设置背光亮度、解锁、打开app
亮屏 adb shell inputkeyevent 26 keyevent 26表示点击power Android adb 点亮和关闭屏幕的命令 # kernel休眠 echo mem > / ...
随机推荐
- DRF 三大认证之身份认证
目录 路由组件补充 三大认证 一.身份认证 1.如何进行身份认证 2.jwt认证规则原理 3.jwt的组成 4.jwt的使用方法 4.1 签发算法 4.2 校验算法 4.3 刷新算法 二.权限认证 三 ...
- spring boot自定义类配置绑定在配置文件中自动提示
在spring boot的日常使用中,我们可能需要使用配置绑定的方式动态配置自定义类的成员变量. 这个时候,我们在配置文件中配置spring默认已有的配置时,只需要输入部分关键字即可自动提示,如下图: ...
- Kafka集群消息积压问题及处理策略
通常情况下,企业中会采取轮询或者随机的方式,通过Kafka的producer向Kafka集群生产数据,来尽可能保证Kafka分区之间的数据是均匀分布的. 在分区数据均匀分布的前提下,如果我们针对要处理 ...
- zabbix 面板graph图上没有数据显示
1. 问题: zabbix_server日志出现大量如下错误: query failed: [1526] Table has no partition for value 1507509984 2. ...
- SpringMVC-01 什么是SpringMVC
SpringMVC-01 什么是SpringMVC 回顾MVC 1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑 ...
- 【RocketMQ源码分析】深入消息存储(1)
最近在学习RocketMQ相关的东西,在学习之余沉淀几篇笔记. RocketMQ有很多值得关注的设计点,消息发送.消息消费.路由中心NameServer.消息过滤.消息存储.主从同步.事务消息等等. ...
- 文件包含-phpinfo()
我也是听朋友说有这个姿势的,github有集成好的环境 先讲一下利用phpinfo上传文件,然后在文件包含的原理: 在给PHP发送POST数据包时,如果数据包里包含文件区块,无论访问的代码中是否有处理 ...
- python学习总结篇(2)——函数
如其他语言一样,除了基本知识外,另外一个重要的板块就是函数了,python中也有函数. 在python中,函数的定义方式为: def 函数名( ): 下面通过几个简单的例子,看看python中的函 ...
- cpu缓存和volatile
目录 CPU缓存的由来 CPU缓存的概念 CPU缓存的意义 缓存一致性协议-MESI协议 Store Buffers Store Forwarding Memory Barriers Invalida ...
- beego 框架用的页面样式模板
https://themequarry.com/category/free 页面样式