利用PyQt5中QLabel组件实现亚克力磨砂效果
作者:之一Yo 时间:2023-12-13 18:33:04
前言
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_()
结果如下:
来源:https://www.cnblogs.com/zhiyiYo/p/15768440.html
标签:PyQt5,QLabel,磨砂
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
使用正则表达式匹配tsql注释语句
2024-01-18 16:42:50
Python读取本地文件并解析网页元素的方法
2022-01-10 08:06:27
asp如何从数据库中删除废旧的电子信箱地址?
2009-11-15 20:04:00
Go语言计算两个经度和纬度之间距离的方法
2024-04-29 13:06:04
MySQL在Linux系统中隐藏命令行中的密码的方法
2024-01-20 03:38:34
Python 实现OpenCV格式和PIL.Image格式互转
2021-08-03 03:41:42
MySQL实现字符串的拼接,截取,替换,查找位置的操作
2024-01-13 13:17:22
Python反爬虫伪装浏览器进行爬虫
2023-07-05 22:33:38
![](https://img.aspxhome.com/file/2023/6/109536_0s.jpg)
如何用Python破解wifi密码过程详解
2021-06-03 05:32:38
![](https://img.aspxhome.com/file/2023/6/72986_0s.gif)
使用豆瓣提供的国内pypi源 <font color=red>原创</font>
2023-05-31 20:39:09
Python中if语句的基本格式实例代码
2023-12-02 14:31:20
如何设置PyCharm中的Python代码模版(推荐)
2022-12-14 03:56:29
![](https://img.aspxhome.com/file/2023/2/76712_0s.png)
Python中反转二维数组的行和列问题
2021-06-24 13:48:27
python实现给微信公众号发送消息的方法
2021-08-25 23:44:57
python3 字符串str和bytes相互转换
2023-03-31 09:12:47
详解css定位与定位应用
2007-05-11 16:52:00
![](https://img.aspxhome.com/file/uploadpic/20075/2007511165230659.png)
Python抓取今日头条街拍图片数据
2021-11-03 12:30:57
![](https://img.aspxhome.com/file/2023/5/92245_0s.jpg)
php将ppt转jpg图片的具体步骤代码
2023-06-12 21:53:33
显示某日期所在星期的所有日期asp代码
2008-06-01 16:05:00
sqlserver exists,not exists的用法
2024-01-22 02:13:26