您现在的位置是:首页 > 编程语言学习 > 前端编程语言 > 文章正文 前端编程语言

Python实现将图片转换为ASCII字符画

2022-08-16 09:21:37 前端编程语言

简介要将图片转换为字符图其实很简单,我们首先将图片转换为灰度图像,这样图片的每个像素点的颜色值都是0到255,然后我们选用一些在文字矩形框...

要将图片转换为字符图其实很简单,我们首先将图片转换为灰度图像,这样图片的每个像素点的颜色值都是0到255,然后我们选用一些在文字矩形框内占用面积从大到小的ASCII码字符,我经过一番观察选择了如下字符:

  1. ascii_chars = "MNHQ$OC67+>!:-. " 

很明显M的笔画比N多,缩小到足够小之后就会体现出M的颜色比N更深,大家若能够找到更能够体现这种特征的字符,也可以替换。

然后我们只需要将图片的目标像素点映射到这批字符上,代码大概就是:

  1. ascii_chars[color*(len(ascii_chars)-1)//255] 

字符画图片生成

先准备好测试图片:

  1. from PIL import Image 
  2. img = Image.open('test.jpg'
  3. img 

然后我们将图片转换为灰度图片并缩放到指定大小:

  1. new_w = 100 
  2. w, h = img.size 
  3. img = img.convert("L").resize((new_w, int(new_w*h//w))) 
  4. w, h = img.size 
  5. data = img.load() 
  6. img 

然后开始绘制字符图片:

  1. from PIL import ImageFont, ImageDraw 
  2.  
  3. f_size = 3 
  4. img_new = Image.new('L', (w * f_size, h * f_size), 255) 
  5. f = ImageFont.truetype('arial.ttf', f_size) 
  6. d = ImageDraw.Draw(img_new) 
  7. n = len(ascii_chars)-1 
  8. for y in range(h): 
  9. for x in range(w): 
  10. char = ascii_chars[data[x, y]*n//255] 
  11. d.text((x * f_size, y * f_size), char, fill=0, font=f) 
  12. img_new 

个人感觉效果还是不错的,我们可以把上述逻辑封装成一个方法:

  1. from PIL import Image, ImageFont, ImageDraw 
  2. def img2charImg(filename, new_wight, font_size): 
  3. "小小明:https://blog.csdn.net/as604049322" 
  4. ascii_chars = "MNHQ$OC67+>!:-. " 
  5. img = Image.open(filename) 
  6. w, h = img.size 
  7. img = img.convert("L").resize((new_wight, int(new_wight*h//w))) 
  8. w, h = img.size 
  9. data = img.load() 
  10. img_new = Image.new('L', (w * font_size, h * font_size), 255) 
  11. f = ImageFont.truetype('arial.ttf', font_size) 
  12. d = ImageDraw.Draw(img_new) 
  13. n = len(ascii_chars)-1 
  14. for y in range(h): 
  15. for x in range(w): 
  16. char = ascii_chars[data[x, y]*n//255] 
  17. d.text((x * font_size, y * font_size), char, fill=0, font=f) 
  18. return img_new 

测试一下:

  1. img2charImg("love.jpg", 200, 2) 

效果:

分别是原图和执行结果:

我们可以通过第二个参数调大字符程度,最终图片的宽度是两个参数相乘。

字符画文字的生成

搞定了字符图片的生成之后,我们考虑直接生成字符文字,但是ASCII码字符在显示时,往往宽度是高度的一半,所以我们在生成字符画文字时需要事先将图片高度压扁一半。

完整代码如下:

  1. from PIL import Image 
  2.  
  3. def img2charTxt(filename, new_wight, txtname): 
  4. "小小明:https://blog.csdn.net/as604049322" 
  5. ascii_chars = "MNHQ$OC67+>!:-. " 
  6. img = Image.open(filename) 
  7. img = img.convert("L"
  8. w, h = img.size 
  9. img = img.resize((new_wight*2, int(new_wight*h//w))) 
  10. w, h = img.size 
  11. data = img.load() 
  12. result = [] 
  13. n = len(ascii_chars)-1 
  14. for y in range(h): 
  15. line = "".join(ascii_chars[data[x, y]*n//255] for x in range(w)) 
  16. line += "\n" 
  17. result.append(line) 
  18. with open(txtname, "w") as f: 
  19. f.writelines(result) 

测试一下:

  1. img2charTxt("test.jpg", 100, "image.txt"

可以看到在文本编辑器中的显示效果是相当不错的。

站点信息