Python 图片转字符画是一个非常简单但实用的小程序。既可以练手熟悉Python,也可以拥有很好的Zhuang Bi效果。
既然是要将图像转成字符串,那么很明显的,必须要用到的就是Python
的图像处理库,也就是大名鼎鼎的PIL
,通过PIL
读取图片的像素信息(灰度图是一维,如果是彩图则有RGB三个维度),再将所选择的字符串与灰度值(像素值)对应,然后输出。
图片转字符串总体来说可以有两种实现方法:
但要知道的是,不管用哪一种方式来进行图片的转换。都需要用PIL
库对图片进行读取。
From PIL import Image
img = Image.open("image.jpg") # 读取文件
img_width = img.size[0] # 提取照片宽度
img_height = img.size[1] # 提取照片高度
通过上面的图像完成了对图像的读取以及尺寸信息的提取。为下面的工作做准备。下面的生成字符画的部分则根据两种不同实现方法有不同的代码。
输出图片格式字符画的核心就是创建空白图片,映射像素值与字符串,将字符串画在之前所创建的空白图像上。这一步需要用到ImageFont
和ImageDraw
模块。
创建空白图片部分:
create_array = np.ndarray([img_height,img_width,3],np.unit8)
create_array[:,:,:] = 255
上面这段代码是从ndarray
对象创建了一张像素值为255的空白图像。
完整代码:
from PIL import Image
from PIL import ImageDraw,ImageFont
import numpy as np
import os
def img2char(img_path):
im = Image.open(img_path) # 读取文件
img_width = im.size[0] # 提取照片宽度
img_height = im.size[1] # 提取照片高度
pix = im.load() # 提取像素值(输出pixel对象)
print("The width of original Image is: %d, the height is %d" % (img_width,img_height))
# 创建图像大小的三维数组
# 将数组内数值设为255 (空白图像)
create_array = np.ndarray([img_height,img_width,3], np.uint8)
create_array[:,:,:] = 255
# 从数组创建图片
create_img = Image.fromarray(create_array)
# 创建要绘制的类和字符串
chart = list("EVA this is Asuka ! ")
font = ImageFont.truetype("arial.ttf", 15, encoding=‘unic‘)
pix_count = 0 # 统计像素数量,初始值设为0
sample_step = 5 # 采样步长,因为原始图片过大,不用每个像素都采。
len_chart = len(chart) # 字符串长度
Draw = ImageDraw.Draw(create_img) # 创建图片绘制对象
for x in range(img_width):
for y in range(img_height):
if x % sample_step == 0 and y % sample_step == 0:
# 按像素和采样率,将字符串绘制入前面所创建的空白图像
Draw.text([x,y], chart[pix_count % len_chart], pix[x,y], font)
print(pix_count)
pix_count +=1
# 保存图像
create_img.save("str_image.jpg")
return create_img
img2char("image.jpg")
输出结果:
可以看到,用这种方法可以话说RGB彩色字符图。根据采样步长的不同也可以调整图像的精细程度。
文本文件相比于上一个方法的缺点就是只能够处理灰度图 (因为最终文件的格式是.txt
),所以第一步就应该是将彩色图像灰度化。RGB与灰度的转换可以使用下面的公式:\(gray = 0.2126*r + 0.7152*g+0.0722*b\)
或者直接调用PIL
库里的自动转换函数Image.convert
来实现RGB与灰度的自动转换。其他部分就比较简单了,对应字符串与灰度值,写入文本,保存输出。
完整代码:
from PIL import Image
import numpy as np
import os
char_list = ‘‘‘@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`‘. ‘‘‘
def get_char(gray_pix):
length = len(char_list) # 确定字符串长度
unit = 256.0/length # 分配每个字符占据的灰度值段
return char_list[int((((length-1)*gray_pix))/256.0)] # 对应灰度值与字符
img_path = ‘image2.jpg‘
img = Image.open(img_path)
img_widht = img.size[0]
img_height = img.size[1]
# 缩放图片(因为有些图片太大所以需要缩放
img = img.resize((int(img_widht*0.75),int(img_height*0.5)),Image.NEAREST)
img_gray = np.array(img.convert(‘L‘),‘f‘) # 彩色图转灰度图
# 创建文本文档并在相对应的位置写入对应字符
text = " "
for i in range(int(img_height*0.5)):
for j in range(int(img_widht*0.75)):
text = text + get_char(img_gray[i,j])
text = text + ‘\n‘
# print(text)
text_name = "str_image2" + ".txt"
with open (text_name,"w") as f:
f.write(text)
# f.close()
输出结果:
可以看到无论是那种方法输出,结果都还是不错的。
原文:https://www.cnblogs.com/AsukaYan/p/14775836.html