用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. 第49天学习打卡(CSS 层次选择器 结构伪类选择器 属性选择器 美化网页元素 盒子模型)

    推荐书籍:码出高效: Java 开发手册 2.2 层次选择器 idea里代码规范是按:ctrl +alt+L快捷键 注释快捷键:ctrl+/ 1.后代选择器:在某个元素的后面 祖爷爷 爷爷 爸爸 你 ...

  2. LeetCode1576. 替换所有的问号

    原题链接 1 class Solution { 2 public: 3 string modifyString(string s) { 4 int lens = s.length(); 5 for(i ...

  3. Android - 利用扩展函数为Bitmap添加文字水印

    <异空间>项目技术分享系列--扩展函数为Bitmap添加文字水印 对图片Bitmap绘制文字水印还是比较常见的需求,毕竟版权意识都在增强(用户可以给自己图片加上用户名),还可以为用户提供更 ...

  4. CNN结构演变总结(二)轻量化模型

    CNN结构演变总结(一)经典模型 导言: 上一篇介绍了经典模型中的结构演变,介绍了设计原理,作用,效果等.在本文,将对轻量化模型进行总结分析. 轻量化模型主要围绕减少计算量,减少参数,降低实际运行时间 ...

  5. MD摘要算法

    import static org.junit.Assert.*; import java.security.MessageDigest; //消息摘要 public class MDCoder { ...

  6. wget 爬取网站网页

    相应的安装命名 yum -y install wget yum -y install setup yum -y install perl wget -r   -p -np -k -E  http:// ...

  7. GreenDao3.2使用详解(增,删,改,查,升级)

    首先看一下效果图: 项目结构如下图所示: 第一步:在build中添加配置如下: projet 目录下的build.gradle dependencies { classpath 'org.greenr ...

  8. salesforce lightning零基础学习(十七) 实现上传 Excel解析其内容

    本篇参考: https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader https://github.com/SheetJS/sheetjs ...

  9. 杨辉三角的实现(Java)

    杨辉三角的实现 一.什么是杨辉三角 杨辉三角是二项式系数在三角形中的一种几何排列.每个数等于它上方两数之和.每行数字左右对称,由1开始逐渐变大.第n行的数字有n项.前n行共[(1+n)n]/2 个数. ...

  10. Jenkins-k8s-helm-eureka-harbor-githab-mysql-nfs微服务发布平台实战

    基于 K8S 构建 Jenkins 微服务发布平台 实现汇总: 发布流程设计讲解 准备基础环境 K8s环境(部署Ingress Controller,CoreDNS,Calico/Flannel) 部 ...