利用PyQt5中QLabel组件实现亚克力磨砂效果

 更新时间:2022年03月25日 09:52:56   作者:之一Yo  
Windows10 在 UWP 应用中支持亚克力画刷,可以在部件的底部绘制亚克力效果的背景图。本文将使用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_()

结果如下:

到此这篇关于利用PyQt5中QLabel组件实现亚克力磨砂效果的文章就介绍到这了,更多相关PyQt5 QLabel磨砂效果内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python实现计算图形面积

    python实现计算图形面积

    这篇文章主要为大家详细介绍了python实现计算图形面积,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • Python3中的多行输入问题

    Python3中的多行输入问题

    这篇文章主要介绍了Python3中的多行输入问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Python贪心算法Greedy Algorithm解决案例小结

    Python贪心算法Greedy Algorithm解决案例小结

    这篇文章主要为大家介绍了Python贪心算法Greedy Algorithm解决案例小结,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 初次部署django+gunicorn+nginx的方法步骤

    初次部署django+gunicorn+nginx的方法步骤

    这篇文章主要介绍了初次部署django+gunicorn+nginx的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Python使用turtule画五角星的方法

    Python使用turtule画五角星的方法

    这篇文章主要介绍了Python使用turtule画五角星的方法,运行该程序可以看到箭头间歇移动绘制五角星的效果,涉及Python使用turtle及time模块绘制图形的相关技巧,需要的朋友可以参考下
    2015-07-07
  • Tensorflow中TFRecord生成与读取的实现

    Tensorflow中TFRecord生成与读取的实现

    TFRecord格式的文件存储形式会很合理的帮我们存储数据,本文主要介绍了Tensorflow中TFRecord生成与读取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • python对象及面向对象技术详解

    python对象及面向对象技术详解

    这篇文章主要介绍了python对象及面向对象技术,结合实例形式详细分析了Python面向对象所涉及的类、对象、方法、属性等概念与使用技巧,需要的朋友可以参考下
    2016-07-07
  • Python实现在PyPI上发布自定义软件包的方法详解

    Python实现在PyPI上发布自定义软件包的方法详解

    在Python中我们经常使用pip来安装第三方Python软件包,其实我们每个人都可以免费地将自己写的Python包发布到PyPI上。本文我们就将详细介绍如何发布测试包,需要的可以参考一下
    2022-06-06
  • django DRF图片路径问题的解决方法

    django DRF图片路径问题的解决方法

    这篇文章主要给大家介绍了关于django DRF图片路径问题的解决方法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • Python+OpenCV解决彩色图亮度不均衡问题

    Python+OpenCV解决彩色图亮度不均衡问题

    当我们换新头像时,常常会遇到图片过暗导致看不到图片内容的情况,本文将介绍如何通过Python和OpenCV解决色彩图亮度不均衡的问题,需要的可以参考一下
    2021-12-12

最新评论