01-Python 圖片轉字元畫

一杯热水發表於2024-05-23
from PIL import Image

"""
    將圖片轉換為字元畫

    圖片轉字元畫是將一張圖片轉換成由字元組成的影像,通常用於在命令列介面或者文字編輯器中顯示。這個過程主要包括以下幾個步驟:

    - 讀取圖片檔案
    - 將圖片轉換為灰度影像
    - 調整圖片的尺寸以適應字元畫的寬度和高度
    - 將灰度值對映到字符集上,生成字元畫


    參考連結:
     - [Image Module](https://pillow.readthedocs.io/en/stable/reference/Image.html)
     - https://blog.csdn.net/m0_73511684/article/details/137026540
     - https://zhuanlan.zhihu.com/p/687097277

    說明:
     - pip install PIL 安裝不了,安裝 Pillow,該庫與PIL介面相容,可以滿足你的影像處理需求。匯入使用 from PIL import Image
"""

class ASCIIart(object):
    def __init__(self, file):
        """
         - file圖片檔案的名字, 傳入引數為檔名進行一個賦值方便後續呼叫, 
         - codelist用於儲存字符集,用於替換每畫素點的灰度值
         - img是PIL庫中Image例項出來的物件,呼叫open方法開啟檔案file
         - count用於儲存字符集的長度
        """
        self.file = file
        self.codelist = """$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. """
        self.img = Image.open(file)
        self.count = len(self.codelist)
 
    def get_char(self, r, g, b, alpha=256):
        """
        用來處理灰度值和字符集的關係
        :return:
        """
        if alpha == 0:
            return " "
        length = self.count  # 獲取字符集的長度
        gary = 0.2126 * r + 0.7152 * g + 0.0722 * b  # 將RGB值轉為灰度值
        unit = 265 / length
        return self.codelist[int(gary / unit)]
 
    def get_new_img(self):
        """
        用於處理圖片是轉換的字元畫不至於失真
        :return:
        """
        w, h = self.img.size
        print(f"圖片的原始寬度和高度為:{w},{h}")
        if not w or not h:
            pass
        else:
            if w <= 299 or h <= 299:
                w = int(w / 1.4)
                h = int(h / 1.4)
            if 300 <= w <= 500 or 300 <= h <= 500:
                w = int(w / 2)
                h = int(h / 2)
            if 500 < w < 1000 or 500 < h < 1000:
                w = int(w / 3.8)
                h = int(h / 3.8)
            if 1000 <= w or 1000 <= h:
                w = int(w / 10)
                h = int(h / 10)
            print(f"修改後圖片的寬度和高度為:{w},{h}")
            """
                https://pillow.readthedocs.io/en/stable/handbook/concepts.html#filters
                
                Image.NEAREST: 低質量
                Image.BILINEAR: 雙線性
                Image.BICUBIC: 三次樣條插值
            """
            im = self.img.resize((w, h), Image.Resampling.LANCZOS)
            return im
 
    def get_str_img(self, im, output=None):
        """
        獲取字串圖片
        :return:
        """
        w, h = im.size
        txt = ""
        for i in range(h):
            for j in range(w):
                txt += self.get_char(*im.getpixel((j, i)))
            txt += "\n"
        # 字元畫輸出到檔案
        if output:
            with open(output, "w") as file:
                file.write(txt)
        else:
            with open("output/output3.txt", "w") as file:
                file.write(txt)
 
 
if __name__ == '__main__':
    file = "image/thing.jpg"
    img = ASCIIart(file)
    im = img.get_new_img()
    img.get_str_img(im)

相關文章