📢作者: 小小明-代码实体
📢博客主页:https://blog.csdn.net/as604049322
📢欢迎点赞 👍 收藏 ⭐留言 📝 欢迎讨论!
📢本文链接:https://blog.csdn.net/as604049322/article/details/126336169
要将图片转换为字符图其实很简单,我们首先将图片转换为灰度图像,这样图片的每个像素点的颜色值都是0到255,然后我们选用一些在文字矩形框内占用面积从大到小的ASCII码字符,我经过一番观察选择了如下字符:
ascii_chars = "MNHQ$OC67+>!:-. "
很明显M的笔画比N多,缩小到足够小之后就会体现出M的颜色比N更深,大家若能够找到更能够体现这种特征的字符,也可以替换。
然后我们只需要将图片的目标像素点映射到这批字符上,代码大概就是:
ascii_chars[ color* ( len ( ascii_chars) - 1 ) // 255 ]
字符画图片生成
先准备好测试图片:
from PIL import Image
img = Image. open ( 'test.jpg' )
img
然后我们将图片转换为灰度图片并缩放到指定大小:
new_w = 100
w, h = img. size
img = img. convert( "L" ) . resize( ( new_w, int ( new_w* h// w) ) )
w, h = img. size
data = img. load( )
img
然后开始绘制字符图片:
from PIL import ImageFont, ImageDraw
f_size = 3
img_new = Image. new( 'L' , ( w * f_size, h * f_size) , 255 )
f = ImageFont. truetype( 'arial.ttf' , f_size)
d = ImageDraw. Draw( img_new)
n = len ( ascii_chars) - 1
for y in range ( h) :
for x in range ( w) :
char = ascii_chars[ data[ x, y] * n// 255 ]
d. text( ( x * f_size, y * f_size) , char, fill= 0 , font= f)
img_new
个人感觉效果还是不错的,我们可以把上述逻辑封装成一个方法:
from PIL import Image, ImageFont, ImageDraw
def img2charImg ( filename, new_wight, font_size) :
"小小明:https://blog.csdn.net/as604049322"
ascii_chars = "MNHQ$OC67+>!:-. "
img = Image. open ( filename)
w, h = img. size
img = img. convert( "L" ) . resize( ( new_wight, int ( new_wight* h// w) ) )
w, h = img. size
data = img. load( )
img_new = Image. new( 'L' , ( w * font_size, h * font_size) , 255 )
f = ImageFont. truetype( 'arial.ttf' , font_size)
d = ImageDraw. Draw( img_new)
n = len ( ascii_chars) - 1
for y in range ( h) :
for x in range ( w) :
char = ascii_chars[ data[ x, y] * n// 255 ]
d. text( ( x * font_size, y * font_size) , char, fill= 0 , font= f)
return img_new
测试一下:
img2charImg( "love.jpg" , 200 , 2 )
效果:
分别是原图和执行结果:
我们可以通过第二个参数调大字符程度,最终图片的宽度是两个参数相乘。
字符画文字的生成
搞定了字符图片的生成之后,我们考虑直接生成字符文字,但是ASCII码字符在显示时,往往宽度是高度的一半,所以我们在生成字符画文字时需要事先将图片高度压扁一半。
完整代码如下:
from PIL import Image
def img2charTxt ( filename, new_wight, txtname) :
"小小明:https://blog.csdn.net/as604049322"
ascii_chars = "MNHQ$OC67+>!:-. "
img = Image. open ( filename)
img = img. convert( "L" )
w, h = img. size
img = img. resize( ( new_wight* 2 , int ( new_wight* h// w) ) )
w, h = img. size
data = img. load( )
result = [ ]
n = len ( ascii_chars) - 1
for y in range ( h) :
line = "" . join( ascii_chars[ data[ x, y] * n// 255 ] for x in range ( w) )
line += "\n"
result. append( line)
with open ( txtname, "w" ) as f:
f. writelines( result)
测试一下:
img2charTxt( "test.jpg" , 100 , "image.txt" )
可以看到在文本编辑器中的显示效果是相当不错的。