Python圖片轉字符畫


Python 圖片轉字符畫是一個非常簡單但實用的小程序。既可以練手熟悉Python,也可以擁有很好的Zhuang Bi效果。

既然是要將圖像轉成字符串,那么很明顯的,必須要用到的就是Python的圖像處理庫,也就是大名鼎鼎的PIL,通過PIL讀取圖片的像素信息(灰度圖是一維,如果是彩圖則有RGB三個維度),再將所選擇的字符串與灰度值(像素值)對應,然后輸出。

圖片轉字符串總體來說可以有兩種實現方法:

  1. 輸出圖片形式。創建一個空白圖像,在圖像上直接在像素上填上字符串。這種方式可以輸出彩色圖像。
  2. 輸出文本形式。這種形式也就是傳統的字符畫。如果是灰度圖,直接讀取灰度值,創建字符串與灰度值的映射,寫入文本並保存。如果是RGB彩圖,則將彩色圖轉換為灰度圖,在映射灰度值與字符串,寫入並輸出。

但要知道的是,不管用哪一種方式來進行圖片的轉換。都需要用PIL庫對圖片進行讀取。

From PIL import Image
img = Image.open("image.jpg") # 讀取文件
img_width = img.size[0] # 提取照片寬度
img_height = img.size[1] # 提取照片高度

通過上面的圖像完成了對圖像的讀取以及尺寸信息的提取。為下面的工作做准備。下面的生成字符畫的部分則根據兩種不同實現方法有不同的代碼。

輸出圖片形式

輸出圖片格式字符畫的核心就是創建空白圖片,映射像素值與字符串,將字符串畫在之前所創建的空白圖像上。這一步需要用到ImageFontImageDraw模塊。

創建空白圖片部分:

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()

輸出結果:

原圖

結果圖

可以看到無論是那種方法輸出,結果都還是不錯的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM