如何在pyqt中实现亚克力磨砂效果的QLabel
前言
Windows10 在 UWP 应用中支持亚克力画刷,可以在部件的底部绘制亚克力效果的背景图。下面我们使用 QLabel 来模拟这个磨砂过程。
实现方法
MSDN 文档中介绍了亚克力材料的配方,包括:高斯模糊、亮度混合、色调混合和噪声纹理。
高斯模糊
我们先来实现高斯模糊的效果,使用 scipy 可以很轻松的实现这个过程:
# coding:utf-8
import numpy as np
from PIL import Image
from PyQt5.QtGui import QPixmap
from scipy.ndimage.filters import gaussian_filter
def gaussianBlur(imagePath: str, blurRadius=18, brightFactor=1, blurPicSize: tuple = None) -> np.ndarray:
""" 对图片进行高斯模糊处理
Parameters
----------
imagePath: str
图片路径
blurRadius: int
模糊半径
brightFactor:float
亮度缩放因子
blurPicSize: tuple
高斯模糊前将图片缩放到指定大小,可以加快模糊速度
Returns
-------
image: `~np.ndarray` of shape `(w, h, c)`
高斯模糊后的图像
"""
if not imagePath.startswith(':'):
image = Image.open(imagePath)
else:
image = Image.fromqpixmap(QPixmap(imagePath))
if blurPicSize:
# 调整图片尺寸,减小计算量,还能增加额外的模糊
w, h = image.size
ratio = min(blurPicSize[0] / w, blurPicSize[1] / h)
w_, h_ = w * ratio, h * ratio
if w_ < w:
image = image.resize((int(w_), int(h_)), Image.ANTIALIAS)
image = np.array(image)
# 处理图像是灰度图的情况
if len(image.shape) == 2:
image = np.stack([image, image, image], axis=-1)
# 对每一个颜色通道分别磨砂
for i in range(3):
image[:, :, i] = gaussian_filter(
image[:, :, i], blurRadius) * brightFactor
return image
亚克力纹理
接下来在 QLabel
上面绘制出亮度混合、色调混合和噪声纹理,一般色调混合使用的颜色是图像的主题色,可以用 colorthief
库提取,这里就不赘述了:
class AcrylicTextureLabel(QLabel):
""" 亚克力纹理标签 """
def __init__(self, tintColor: QColor, luminosityColor: QColor, noiseOpacity=0.03, parent=None):
"""
Parameters
----------
tintColor: QColor
RGB 主色调
luminosityColor: QColor
亮度层颜色
noiseOpacity: float
噪声层透明度
parent:
父级窗口
"""
super().__init__(parent=parent)
self.tintColor = QColor(tintColor)
self.luminosityColor = QColor(luminosityColor)
self.noiseOpacity = noiseOpacity
self.noiseImage = QImage('resource/noise.png')
self.setAttribute(Qt.WA_TranslucentBackground)
def setTintColor(self, color: QColor):
""" 设置主色调 """
self.tintColor = color
self.update()
def paintEvent(self, e):
""" 绘制亚克力纹理 """
acrylicTexture = QImage(64, 64, QImage.Format_ARGB32_Premultiplied)
# 绘制亮度层
acrylicTexture.fill(self.luminosityColor)
# 绘制主色调
painter = QPainter(acrylicTexture)
painter.fillRect(acrylicTexture.rect(), self.tintColor)
# 绘制噪声
painter.setOpacity(self.noiseOpacity)
painter.drawImage(acrylicTexture.rect(), self.noiseImage)
acrylicBrush = QBrush(acrylicTexture)
painter = QPainter(self)
painter.fillRect(self.rect(), acrylicBrush)
用到的噪声图像如下图所示:
亚克力标签
最后在 QLabel
上叠加磨砂图像和亚克力纹理,可以通过 Image.toqpixmap()
将 Image
转换为 QPixmap
:
class AcrylicLabel(QLabel):
""" 亚克力标签 """
def __init__(self, blurRadius: int, tintColor: QColor, luminosityColor=QColor(255, 255, 255, 0),
maxBlurSize: tuple = None, parent=None):
"""
Parameters
----------
blurRadius: int
磨砂半径
tintColor: QColor
主色调
luminosityColor: QColor
亮度层颜色
maxBlurSize: tuple
最大磨砂尺寸,越小磨砂速度越快
parent:
父级窗口
"""
super().__init__(parent=parent)
self.imagePath = ''
self.blurPixmap = QPixmap()
self.blurRadius = blurRadius
self.maxBlurSize = maxBlurSize
self.acrylicTextureLabel = AcrylicTextureLabel(
tintColor, luminosityColor, parent=self)
def setImage(self, imagePath: str):
""" 设置图片 """
if imagePath == self.imagePath:
return
self.imagePath = imagePath
image = Image.fromarray(gaussianBlur(
imagePath, self.blurRadius, 0.85, self.maxBlurSize))
self.blurPixmap = image.toqpixmap() # type:QPixmap
self.setPixmap(self.blurPixmap)
self.adjustSize()
def setTintColor(self, color: QColor):
""" 设置主色调 """
self.acrylicTextureLabel.setTintColor(color)
def resizeEvent(self, e):
super().resizeEvent(e)
self.acrylicTextureLabel.resize(self.size())
self.setPixmap(self.blurPixmap.scaled(
self.size(), Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation))
测试
下面是测试用的埃罗芒阿老师:
代码如下:
# coding:utf-8
import sys
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QApplication
from acrylic import AcrylicLabel
app = QApplication(sys.argv)
w = AcrylicLabel(20, QColor(105, 114, 168, 102))
w.setImage('resource/ClariS_ヒトリゴト (アニメ盤).jpg')
w.show()
app.exec_()
结果如下:
如何在pyqt中实现亚克力磨砂效果的QLabel的更多相关文章
- 如何在pyqt中实现窗口磨砂效果
磨砂效果的实现思路 这两周一直在思考怎么在pyqt上实现窗口磨砂效果,网上搜了一圈,全都是 C++ 的实现方法.正好今天查python的官方文档的时候看到了 ctypes 里面的 HWND,想想倒不如 ...
- 如何在pyqt中实现win10亚克力效果
亚克力效果的实现思路 上一篇博客<如何在pyqt中实现窗口磨砂效果> 中实现了win7中的Aero效果,但是和win10的亚克力效果相比,Aero还是差了点内味.所以今天早上又在网上搜了一 ...
- 如何在pyqt中通过调用 SetWindowCompositionAttribute 实现Win10亚克力效果
亚克力效果 在<如何在pyqt中实现窗口磨砂效果>和<如何在pyqt中实现win10亚克力效果>中,我们调用C++ dll来实现窗口效果,这种方法要求电脑上必须装有MSVC.V ...
- 如何在pyqt中自定义无边框窗口
前言 之前写过很多关于无边框窗口并给窗口添加特效的博客,按照时间线罗列如下: 如何在pyqt中实现窗口磨砂效果 如何在pyqt中实现win10亚克力效果 如何在pyqt中通过调用SetWindowCo ...
- 如何在pyqt中实现带动画的动态QMenu
弹出菜单的视觉效果 QLineEdit 原生的菜单弹出效果十分生硬,而且样式很丑.所以照着Groove中单行输入框弹出菜单的样式和动画效果写了一个可以实现动态变化Item的弹出菜单,根据剪贴板的内容是 ...
- 如何在pyqt中在实现无边框窗口的同时保留Windows窗口动画效果(一)
无边框窗体的实现思路 在pyqt中只要 self.setWindowFlags(Qt.FramelessWindowHint) 就可以实现边框的去除,但是没了标题栏也意味着窗口大小无法改变.窗口无法拖 ...
- 如何在pyqt中给无边框窗口添加DWM环绕阴影
前言 在之前的博客<如何在pyqt中通过调用SetWindowCompositionAttribute实现Win10亚克力效果>中,我们实现了窗口的亚克力效果,同时也用SetWindowC ...
- 如何在 pyqt 中捕获并处理 Alt+F4 快捷键
前言 如果在 Windows 系统的任意一个窗口中按下 Alt+F4,默认行为是关闭窗口(或者最小化到托盘).对于使用了亚克力效果的窗口,使用 Alt+F4 最小化到托盘,再次弹出窗口的时候可能出现亚 ...
- 如何在pyqt中使用 QGraphicsView 实现图片查看器
前言 在 PyQt 中可以使用很多方式实现照片查看器,最朴素的做法就是重写 QWidget 的 paintEvent().mouseMoveEvent 等事件,但是如果要在图像上多添加一些形状,那么在 ...
随机推荐
- 破解UltraEdit64 Version 28.20.0.92 技术分享。
本文为原创作品,转载请注明出处,作者:Chris.xisaer E-mail:69920579@qq.com QQ群3244694 补丁程序下载地址:https://download.csdn.net ...
- 序列化之serialVersionUID
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 序列化ID起着关键的作用,java的序列化机制是通过在运行时判断类的serialVer ...
- MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP
MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP,其中 DATE 类型用于表示日期,但是不会包含时间,格式为 YYYY-MM-DD,而 DATETIME 和 T ...
- 【已开源】Flutter 穿山甲广告插件的集成-FlutterAds
前言 上篇文章我们聊了国内各大广告平台对 Flutter 的支持程度和我为什么创建 FlutterAds 来构建优质的 Flutter 广告插件,帮助开发者获利.本篇我们来看看Flutter 穿山甲广 ...
- python 插入mysql数据库字符串中含有单引号或双引号报错
出现问题场景:使用mysql数据库管理接口测试用例,新增接口用例时,传入的paras内容,有多层嵌套的时候,就会有["]双引号括住[']单引号的情况,可能在插入单双引号的数据到数据库的时候, ...
- SQLAlchemy(十)
ORM操作在实际项目中的应用非常多,涉及到的框架也是根据不同的项目有不同的处理模块,不过操作流程和步骤都是大同小异基本没有什么太大变化,唯一需要注意的就是在实际操作过程中你要使用的ORM框架的处理性能 ...
- vue组件中的.sync修饰符使用
在vue的组件通信props中,一般情况下,数据都是单向的,子组件不会更改父组件的值,那么vue提供.sync作为双向传递的关键字,实现了父组件的变动会传递给子组件,而子组件的carts改变时,通过事 ...
- Scrapy的Item_loader机制详解
一.ItemLoader与Item的区别 ItemLoader是负责数据的收集.处理.填充,item仅仅是承载了数据本身 数据的收集.处理.填充归功于item loader中两个重要组件: 输入处理i ...
- Chromium Windows Build
https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/windows_build_instructions.md ...
- 计算机视觉--CV技术指南文章汇总
前言 本文汇总了过去本公众号原创的.国外博客翻译的.从其它公众号转载的.从知乎转载的等一些比较重要的文章,并按照论文分享.技术总结三个方面进行了一个简单分类.点击每篇文章标题可阅读详细内容 欢迎关注 ...