目录
项目下载:https://download.csdn.net/download/weixin_42253874/13985690
引言
打印字符print(text)是大家在编程学习初期最最经常使用的操作,而打印出来的字符多是没有颜色的,或者通过复杂的换行方式才能达到字符画的效果。下面来介绍一种新的玩法
--->
根据原图颜色进行图像文字填充使图像含有更深一层的意思. 嘿嘿嘿,,,,
有一天,小明同学突然给同桌的小美发了一张这样的图片
小美心想,这他丫的是要告诉我大爱无疆吗?质量还这么差,,, 小美脑子昏沉沉,越想越不明白。回到家里,有经验的老妈点开图像一看,,。。。。
小明和小美过上了幸福、美好的生活,,,,,,,全 剧 终。
不明白的同学点开“爱”看一下哈。下面进入正题。
项目介绍
原理:根据原图像素的颜色重新绘制另一张图,比如跨五个像素填充一个字,如何保证尺寸大小一致呢?选定宋体中文,字号大小为FontSize,原图像大小为imgW*imgH,可以将我们需要绘制的图看成是一个(imgW/FontSize)*(imgFontSize)大小的文字矩阵.填充文字的时候使用文字循环填充方式,而文字的颜色为原图中相应的颜色. 如文字(x,y)的颜色为image(x*FontSize,y*FontSize)该像素点的颜色.
打包:使用pyinstaller进行py界面程序打包,注意一定要使用虚拟环境,不然可能会出现下面错误,pyinstaller打包的时候回连带虚拟环境一起打包,所以不会出现丢包的问题了
This application failed to start because it could not find or load the Qt platform plugin "window...
需要安装PyQt环境:CSDN
软件界面:
主要代码
conversion.py文件
from PIL import Image,ImageDraw,ImageFont # 导入图像处理模块(图像、图像绘制、图像文字)
import numpy # 导入numpy模块,用于创建数组对象
from PyQt5 import QtGui
scale = 1 # 生成后图片的缩放比例
default_char ='$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft我爱Python' # 默认字符
"""
该方法用于实现字符画图片的转换与生成
import_img:该参数为指定原图片的路径
export_img:该参数为转换后字符画图片输出路径
input_char:该参数为自定义字符画中的字符内容,如果该参数为空将使用默认参数
pix_distance:该参数为字符画图片的字符密度,3为清晰,4为一般,5为字符
"""
def picture_conversion(import_img, export_img = None,input_char = '',pix_distance=''):
# 导入图片处理
img = Image.open(import_img) #读取图片信息
img_pix = img.load() # 加载图片像素
img_width = img.size[0] # 获取图片宽度
img_height = img.size[1] # 获取图片高度
#创建新图片画布
canvas_array = numpy.ndarray((img_height*scale, img_width*scale, 3), numpy.uint8) # 创建画布数组对象
canvas_array[:, :, :] = 255 # 设置画布的三元色(255 255 255)为白色
new_image = Image.fromarray(canvas_array) # 根据画布创建新的图像
img_draw = ImageDraw.Draw(new_image) # 创建图像绘制对象
# 判断字符画所使用的字符
if input_char=='':
char_list = list(default_char) # 指定默认显示的字符列表
else:
char_list =list(input_char)
# 判断选择的清晰度
if pix_distance=='清晰':
pix_distance=8
elif pix_distance=='一般':
pix_distance=12
elif pix_distance=='字符':
pix_distance=15
font = ImageFont.truetype('simsun.ttc', pix_distance) # 字库类型
#开始绘制
pix_count = 0 # 记录绘制的字符像素点数量
table_len = len(char_list) # 字符长度
for y in range(img_height): # 根据图片高度,获取y坐标
for x in range(img_width): # 根据图片宽度,获取x坐标
if x % pix_distance == 0 and y % pix_distance == 0: # 判断字符间隔位置
# 实现根据图片像素绘制字符
img_draw.text((x*scale, y*scale), char_list[pix_count % table_len], img_pix[x, y], font)
pix_count += 1 # 叠加绘制字符像素点数量
# 保存
if export_img is not None: # 判断如果设置了新图片保存的名称与路径
new_image.save(export_img) # 实现字符图片的保存
export = QtGui.QPixmap() # 打开位图-
print(export.width())
return False # 通知说明已经转换完毕
show_window.py主程序文件
from window import Ui_MainWindow # 导入主窗体UI类
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog # 导入qt窗体类
from PyQt5 import QtGui
import sys # 导入系统模块
import _thread # 导入线程模块
import time # 导入时间模块
import conversion # 导入用于转换的模块
# 主窗体初始化类
class Main(QMainWindow, Ui_MainWindow):
def __init__(self):
super(Main, self).__init__()
self.setupUi(self)
# 开启自动填充背景
self.centralwidget.setAutoFillBackground(True)
palette = QtGui.QPalette() # 调色板类
palette.setBrush(QtGui.QPalette.Background, QtGui.QBrush(
QtGui.QPixmap('img/bg.png'))) # 设置背景图片
self.centralwidget.setPalette(palette) # 设置调色板
input_img = QtGui.QPixmap('img/input_test.png') # 打开位图
self.input_img.setPixmap(input_img) # 设置位图
export_img = QtGui.QPixmap('img/output_test.png') # 打开位图
self.export_img.setPixmap(export_img) # 设置位图
# 打开图片文件路径
def openfile(self):
# 打开文件的窗体,进行图片的选择
openfile_name = QFileDialog.getOpenFileName()
if openfile_name[0] != '':
self.input_path = openfile_name[0] # 获取选中的图片路径
self.show_input_img(self.input_path) # 调用显示导入图片的方法
# 显示导入的图片
def show_input_img(self,file_path):
input_img = QtGui.QPixmap(file_path) # 打开位图
self.input_img.setPixmap(input_img) # 设置位图
# 启动转换图片
def start_conversion(self):
if hasattr(main,'input_path'):
self.gif = QtGui.QMovie('img\loding.gif') # 加载gif图片
self.loding.setMovie(self.gif) # 设置gif图片
self.gif.start() # 启动图片,实现等待gif图片的显示
# 线程启动转换方法,避免与主窗体冲突
_thread.start_new_thread(lambda: self.is_conversion(main.input_path),())
else:
print('没有选择指定的图片路径!')
# 转换方法,方便线程启动
def is_conversion(self, file_path):
t = str(int(time.time())) # 当前时间戳,秒级
# 转换后的字符画图片路径
export_path = 'export_img\\export_img'+t+'.png'
input_char = main.textEdit.toPlainText() # 获取输入的字符内容
definition =main.comboBox.currentText() # 获取选中的文字
# 调用转换字符画的方法file_path为输入图片路径,
is_over = conversion.picture_conversion(file_path,export_path,input_char,definition)
if is_over == False: # 判断图片是否转换完毕
self.loding.clear() # 转换完毕就将等待gif图片清理掉
main.show_export_img(export_path) # 调用显示转换后的字符换图片方法
# 显示转换后的字符画图片
def show_export_img(self,file_path):
export_img = QtGui.QPixmap(file_path) # 打开位图
self.export_img.setPixmap(export_img) # 设置位图
if __name__ == '__main__':
app = QApplication(sys.argv) # 创建GUI对象
main = Main() # 创建主窗体ui类对象
main.show() # 显示主窗体
main.pushButton_input.clicked.connect(main.openfile) # 导入文件按钮指定打开图片文件路径的事件
main.pushButton_conversion.clicked.connect(main.start_conversion) # 转换按钮指定启动转换图片的方法
sys.exit(app.exec_()) # 除非退出程序关闭窗体,否则一直运行
界面及资源文件这里不再赘述,都是PYQT5生成并转换的
项目下载:https://download.csdn.net/download/weixin_42253874/13985690
venv为虚拟环境
打包为exe
在pycharm的终端中执行:pyinstaller -F show_window.py
或者你已经有了spec文件的,可以执行:pyinstaller show_window.spec
此时会多出一个dist文件夹,里面有我们需要的exe.开心的不行,双击执行
效果不对啊,还多出来一个控制台....,我们修改一下spec文件:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['show_window.py'],
pathex=['D:\\BaiduNetdiskDownload\\chara_painting'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='show_window',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False )
其他都不重要,总要的是最后一句console=False
再来一次:pyinstaller show_window.spec
最后请把exe放到show_window.py同级目录,这样资源文件就可以调用成功了,或者资源文件放到dist.....