我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python+PyQT5实现手绘图片生成器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python+PyQT5实现手绘图片生成器

手绘图片生成器可以将导入的彩色图片通过python分析光源、灰度等操作生成手绘图片。

file

UI界面的整体部分代码块,UI界面的设计比较简单。效果在上面的图片展示。

class HandImage(QWidget):
    def __init__(self):
        super(HandImage, self).__init__()
        self.init_ui()

    def init_ui(self):
        '''
        UI界面组件及布局
        :return:
        '''
        self.setWindowTitle('手绘图片生成器   公众号:[Python 集中营]')
        self.setWindowIcon(QIcon('手绘图标.ico'))

        self.setFixedWidth(500)

        self.sou_im_path = QLineEdit()
        self.sou_im_path.setReadOnly(True)

        self.sou_im_path_btn = QPushButton()
        self.sou_im_path_btn.setText('源图片')
        self.sou_im_path_btn.clicked.connect(self.sou_im_path_btn_clk)

        self.dir_path = QLineEdit()
        self.dir_path.setReadOnly(True)

        self.dir_path_btn = QPushButton()
        self.dir_path_btn.setText('存储')
        self.dir_path_btn.clicked.connect(self.dir_path_btn_clk)

        self.start_btn = QPushButton()
        self.start_btn.setText('开始绘制图像')
        self.start_btn.clicked.connect(self.start_btn_clk)

        grid = QGridLayout()
        grid.addWidget(self.sou_im_path, 0, 0, 1, 1)
        grid.addWidget(self.sou_im_path_btn, 0, 1, 1, 1)
        grid.addWidget(self.dir_path, 1, 0, 1, 1)
        grid.addWidget(self.dir_path_btn, 1, 1, 1, 1)
        grid.addWidget(self.start_btn, 2, 0, 1, 2)

        self.thread_ = WorkThread(self)
        self.thread_.finished.connect(self.finished)

        self.setLayout(grid)

    # UI界面上的槽函数

    def sou_im_path_btn_clk(self):
        '''
        选择源图片并设置路径
        :return:
        '''
        im_path = QFileDialog.getOpenFileName(self, os.getcwd(), '打开图片', 'Image File(*.jpg);;Image File(*.png)')
        self.sou_im_path.setText(im_path[0])

    def dir_path_btn_clk(self):
        '''
        选择存储路径并设置路径
        :return:
        '''
        dir_path = QFileDialog.getExistingDirectory(self, os.getcwd(), '选择路径')
        self.dir_path.setText(dir_path)

    def start_btn_clk(self):
        '''
        开始按钮绑定的槽函数
        :return:
        '''
        self.start_btn.setEnabled(False)
        self.thread_.start()

    def finished(self, finished):
        '''
        用于子线程传递完成信号的槽函数
        :param finished: 信号变量
        :return:
        '''
        if finished is True:
            self.start_btn.setEnabled(True)

其中绘图用到的第三方库只有两个,主要的还是Pillow图像处理库,还有就是numpy科学计算库用于一些数组计算等的操作。

将第三方的处理库导入到代码块中

from PIL import Image  # 图像处理模块
import numpy as np  # 科学计算库

# PyQt5界面制作及样式、核心组件
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

# 应用基础操作相关
import sys
import os

创建用于专门手绘图像的子线程类,将UI界面的处理逻辑和生成图像的处理逻辑分开不至于产生无响应的卡死状态。

class WorkThread(QThread):
    finished = pyqtSignal(bool)

    def __init__(self, parent=None):
        super(WorkThread, self).__init__(parent)
        self.parent = parent
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        # 源图片路径
        sou_im_path = self.parent.sou_im_path.text().strip()
        # 存储路径
        dir_path = self.parent.dir_path.text().strip()
        if sou_im_path == '' or dir_path == '':
            self.finished.emit(True)
            return
        # 打开需要进行转的图像,并进行参数设置,取出来的参数主要图像的一些梯度值。最后进行数组保存。
        vals = np.asarray(Image.open(sou_im_path).convert('L')).astype('float')

        '''图像参数处理'''
        depth = 12.0  # 设置初始化深度
        gray_vals = np.gradient(vals)  # 提取图像灰度的梯度值
        gray_x, gray_y = gray_vals  # 单独提取横坐标与纵坐标的灰度值
        print('当前横坐标的灰度值:', gray_x)
        print('当前纵坐标的灰度值:', gray_y)

        # 重新设置横坐标合纵坐标的灰度值
        gray_x = gray_x * depth / 100.0
        gray_y = gray_y * depth / 100.0

        # 根据numpy.sqrt()函数计算横坐标和纵坐标灰度值的平方根
        gray_sqrt = np.sqrt(gray_x ** 2 + gray_y ** 2 + 1.0)

        # 重新计算X轴、Y轴、Z轴的光源
        light_x = gray_x / gray_sqrt
        light_y = gray_y / gray_sqrt
        light_z = 1.0 / gray_sqrt

        # 计算光源的方位角度、俯视角度
        agnle_el = np.pi / 2.2  # 俯视角度
        agnle_az = np.pi / 4.  # 方位角度

        # 分别计算光源对X轴、Y轴、Z轴的影响
        dx = np.cos(agnle_el) * np.cos(agnle_az)  # 光源对x 轴的影响
        dy = np.cos(agnle_el) * np.sin(agnle_az)  # 光源对y 轴的影响
        dz = np.sin(agnle_el)  # 光源对z 轴的影响

        # 设置光源归一化处理
        light = 255 * (dx * light_x + dy * light_y + dz * light_z)
        light = light.clip(0, 255)

        # 重新构建图像
        image = Image.fromarray(light.astype('uint8'))
        image.save(dir_path + '/手绘图像.jpg')
        self.finished.emit(True)
        print('手绘图像绘制完成!')

主要代码块实现都在上面了,下面将展示完整的代码

完整代码

# -*- coding:utf-8 -*-
# @author Python 集中营
# @date 2022/2/10
# @file test2.py

# done

# 手绘图片生成器:以雪容融为例一键生成...

# 手绘图片生成器可以将导入的彩色图片通过python分析光源、灰度等操作生成手绘图片。

# 其中绘图用到的第三方库只有两个,主要的还是Pillow图像处理库,还有就是numpy科学计算库用于一些数组计算等的操作。

# 将第三方的处理库导入到代码块中
from PIL import Image  # 图像处理模块
import numpy as np  # 科学计算库

# PyQt5界面制作及样式、核心组件
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

# 应用基础操作相关
import sys
import os

# 创建用于专门手绘图像的子线程类,将UI界面的处理逻辑和生成图像的处理逻辑分开不至于产生无响应的卡死状态。
class WorkThread(QThread):
    finished = pyqtSignal(bool)

    def __init__(self, parent=None):
        super(WorkThread, self).__init__(parent)
        self.parent = parent
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        # 源图片路径
        sou_im_path = self.parent.sou_im_path.text().strip()
        # 存储路径
        dir_path = self.parent.dir_path.text().strip()
        if sou_im_path == '' or dir_path == '':
            self.finished.emit(True)
            return
        # 打开需要进行转的图像,并进行参数设置,取出来的参数主要图像的一些梯度值。最后进行数组保存。
        vals = np.asarray(Image.open(sou_im_path).convert('L')).astype('float')

        '''图像参数处理'''
        depth = 12.0  # 设置初始化深度
        gray_vals = np.gradient(vals)  # 提取图像灰度的梯度值
        gray_x, gray_y = gray_vals  # 单独提取横坐标与纵坐标的灰度值
        print('当前横坐标的灰度值:', gray_x)
        print('当前纵坐标的灰度值:', gray_y)

        # 重新设置横坐标合纵坐标的灰度值
        gray_x = gray_x * depth / 100.0
        gray_y = gray_y * depth / 100.0

        # 根据numpy.sqrt()函数计算横坐标和纵坐标灰度值的平方根
        gray_sqrt = np.sqrt(gray_x ** 2 + gray_y ** 2 + 1.0)

        # 重新计算X轴、Y轴、Z轴的光源
        light_x = gray_x / gray_sqrt
        light_y = gray_y / gray_sqrt
        light_z = 1.0 / gray_sqrt

        # 计算光源的方位角度、俯视角度
        agnle_el = np.pi / 2.2  # 俯视角度
        agnle_az = np.pi / 4.  # 方位角度

        # 分别计算光源对X轴、Y轴、Z轴的影响
        dx = np.cos(agnle_el) * np.cos(agnle_az)  # 光源对x 轴的影响
        dy = np.cos(agnle_el) * np.sin(agnle_az)  # 光源对y 轴的影响
        dz = np.sin(agnle_el)  # 光源对z 轴的影响

        # 设置光源归一化处理
        light = 255 * (dx * light_x + dy * light_y + dz * light_z)
        light = light.clip(0, 255)

        # 重新构建图像
        image = Image.fromarray(light.astype('uint8'))
        image.save(dir_path + '/手绘图像.jpg')
        self.finished.emit(True)
        print('手绘图像绘制完成!')


# UI界面的整体部分代码块,UI界面的设计比较简单。效果在下面的图片展示。

class HandImage(QWidget):
    def __init__(self):
        super(HandImage, self).__init__()
        self.init_ui()

    def init_ui(self):
        '''
        UI界面组件及布局
        :return:
        '''
        self.setWindowTitle('手绘图片生成器   公众号:[Python 集中营]')
        self.setWindowIcon(QIcon('手绘图标.ico'))

        self.setFixedWidth(500)

        self.sou_im_path = QLineEdit()
        self.sou_im_path.setReadOnly(True)

        self.sou_im_path_btn = QPushButton()
        self.sou_im_path_btn.setText('源图片')
        self.sou_im_path_btn.clicked.connect(self.sou_im_path_btn_clk)

        self.dir_path = QLineEdit()
        self.dir_path.setReadOnly(True)

        self.dir_path_btn = QPushButton()
        self.dir_path_btn.setText('存储')
        self.dir_path_btn.clicked.connect(self.dir_path_btn_clk)

        self.start_btn = QPushButton()
        self.start_btn.setText('开始绘制图像')
        self.start_btn.clicked.connect(self.start_btn_clk)

        grid = QGridLayout()
        grid.addWidget(self.sou_im_path, 0, 0, 1, 1)
        grid.addWidget(self.sou_im_path_btn, 0, 1, 1, 1)
        grid.addWidget(self.dir_path, 1, 0, 1, 1)
        grid.addWidget(self.dir_path_btn, 1, 1, 1, 1)
        grid.addWidget(self.start_btn, 2, 0, 1, 2)

        self.thread_ = WorkThread(self)
        self.thread_.finished.connect(self.finished)

        self.setLayout(grid)

    # UI界面上的槽函数

    def sou_im_path_btn_clk(self):
        '''
        选择源图片并设置路径
        :return:
        '''
        im_path = QFileDialog.getOpenFileName(self, os.getcwd(), '打开图片', 'Image File(*.jpg);;Image File(*.png)')
        self.sou_im_path.setText(im_path[0])

    def dir_path_btn_clk(self):
        '''
        选择存储路径并设置路径
        :return:
        '''
        dir_path = QFileDialog.getExistingDirectory(self, os.getcwd(), '选择路径')
        self.dir_path.setText(dir_path)

    def start_btn_clk(self):
        '''
        开始按钮绑定的槽函数
        :return:
        '''
        self.start_btn.setEnabled(False)
        self.thread_.start()

    def finished(self, finished):
        '''
        用于子线程传递完成信号的槽函数
        :param finished: 信号变量
        :return:
        '''
        if finished is True:
            self.start_btn.setEnabled(True)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = HandImage()
    main.show()
    sys.exit(app.exec_())

以上就是Python+PyQT5实现手绘图片生成器的详细内容,更多关于Python PyQT5手绘图片生成器的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python+PyQT5实现手绘图片生成器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么用Python+PyQT5实现手绘图片生成器

本篇内容主要讲解“怎么用Python+PyQT5实现手绘图片生成器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Python+PyQT5实现手绘图片生成器”吧!UI界面的整体部分代码块,U
2023-06-29

基于PyQt5如何制作一个gif动态图片生成器

这篇文章的内容主要围绕基于PyQt5如何制作一个gif动态图片生成器进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!这个小工具制作的目的是为了将多张图
2023-06-28

怎么用Python实现随机生成图片验证码

本篇内容主要讲解“怎么用Python实现随机生成图片验证码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Python实现随机生成图片验证码”吧!导入模块import randomfrom
2023-06-26

Vue如何实现图片验证码生成

这篇文章主要介绍“Vue如何实现图片验证码生成”,在日常操作中,相信很多人在Vue如何实现图片验证码生成问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue如何实现图片验证码生成”的疑惑有所帮助!接下来,请跟
2023-06-29

PHP中怎么实现生成图片水印

PHP中怎么实现生成图片水印,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。文本水印我们使用函数watermark_text()来生成文本水印,你必须先指定字体源文件、字体大
2023-06-17

C#图片处理如何生成缩略图的实现

本文主要介绍了C#图片处理如何生成缩略图的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-02-07

python如何实现生成词云图

这篇文章主要介绍python如何实现生成词云图,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!生成的词云图,如下:安装wordcloud,jieba,其他包自行安装:conda install -c conda-for
2023-06-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录