1. 程式人生 > >Python實戰1- 圖片轉字元畫

Python實戰1- 圖片轉字元畫

一、步驟

分析:字元畫原理是將圖片的灰度值與個人設定的字符集之間建立對映關係,不同區間的灰度值對應不同的字元,之後將圖片每一個畫素對應的字元打印出來,即可獲得字元畫

  1. 將原圖片轉化為灰度圖片 方案一:利用灰度公式將畫素的 RGB 值對映到灰度值 gray = 0.2126 * r + 0.7152 * g + 0.0722 * b 方案二:利用PIL庫所帶的convert(“L”)函式轉化圖片

  2. 將圖片的灰度值與個人設定的字符集之間建立對映關係 可以自己設定,也可以找網上教程裡給出的,下面將給出兩種參考方案 方案一:

    ascii_char = list("[email protected]
    %8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")

    方案二:

    ascii_char = list("qwertyuiop[]asdfghjkl;'zxcvbnm,./`[email protected]#$%^&<()*+{}:"?> |")
    

    經測試,方案二生成的圖片真實度更高

  3. 將字串儲存到txt檔案

二、程式碼實現

注:IDE為Spyder,Python版本為3.6,推薦使用Anaconda,自帶Pillow庫。否則要提前安裝好pillow。 pillow庫安裝教程:

  1. 用管理員身份開啟命令提示符
  2. 輸入pip install pillow

程式碼實現如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Sep 28 23:23:44 2018

@author: PastoralDog
"""
from PIL import Image

class ASCIIart(object):
    def __init__(self,file):
        self.file=file
        self.codelist = """qwertyuiop[]asdfghjkl;'zxcvbnm,./`[email protected]
#$%^&<()*+{}:"?> |""" self.img=Image.open(file) self.count=len(self.codelist) def to_ASCII(self): img = self.img.convert("L") asciilist = '' for h in range(0,img.size[1]): for w in range(0,img.size[0]): gray = img.getpixel((w,h)) pos = gray/256 #asciilist = asciilist + self.codelist[int((self.count-1)*pos)] asciilist = asciilist + self.codelist[int((self.count-1)*pos)]+" "+self.codelist[int((self.count-1)*pos)] asciilist = asciilist+"\n" return asciilist def to_txt(self): outfile = open('ASCIIart.txt', 'w') outfile.write(self.to_ASCII()) outfile.close() def _resize(self,rate): width = self.img.size[0] height = self.img.size[1] scale = width / height self.img = self.img.resize((int(width*rate), int(width*rate/scale) )) if __name__ == '__main__': file="test.jpg" img=ASCIIart(file) img.to_txt()

三、出現的問題及解決方案

  1. 影象失真嚴重 採用方案一的編碼生成的字元畫效果不是很好,改用方案二後得到解決

  2. 影象左右過於窄 我們以下圖為例 原圖 程式碼1

    程式碼2 第二張核心程式碼:

    asciilist = asciilist + self.codelist[int((self.count-1)*pos)]

    第三張核心程式碼:

    asciilist = asciilist + self.codelist[int((self.count-1)*pos)]+" "+self.codelist[int((self.count-1)*pos)]
    

    由於第二張過窄,我們就加點東西(" "+self.codelist[int((self.count-1)*pos))使它豐滿起來

本人水平有限,歡迎大家提出問題與建議。若程式碼有看不懂的地方,也歡迎提出!