Python實現圖片轉ASCII文字圖形
阿新 • • 發佈:2019-01-10
Python實現圖片轉ASCII文字圖形
視訊講解:https://v.qq.com/x/page/u0681ujebmb.html
演示PPT及原始碼下載:https://download.csdn.net/download/lly1122334/10467749
#coding=utf-8
import sys, random, argparse#argparse庫用於命令列解析
import numpy as np #numpy庫用於大型矩陣計算
import math
from PIL import Image #PIL庫是Python事實上的影象處理標準庫
# 圖片轉ASCII的基本原理是將灰度圖片分割成眾多小網格,將小網格的平均亮度計算出來用不同亮度字元代替
# 灰度梯度對應字元可參考:http://paulbourke.net/dataformats/asciiart/
# 70級灰度梯度(越來越亮)
gscale1 = "[email protected]%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
# 10級灰度梯度
gscale2 = '@%#*+=-:. '
#計算每一小塊平均亮度
def getAverageL(image) :
im = np.array(image)#小塊轉成二維陣列
w, h = im.shape#儲存小塊尺寸
return np.average(im.reshape(w * h))#將二維陣列轉成一維,求均值
#根據每一小塊平均亮度匹配ASCII字元
def covertImageToAscii(fileName, cols, scale, moreLevels):
global gscale1, gscale2#灰度梯度
image = Image.open(fileName).convert('L')#開啟圖片並轉換成灰度圖
W, H = image.size[0 ], image.size[1]#儲存影象寬高
print("影象寬高: %dx%d" % (W, H))
w = W / cols#計算小塊寬度
h = w / scale#計算小塊高度,此處除垂直比例係數用於減少影象違和感,經測試scale為0.43時效果較好
rows = int(H / h)#計算行數
print("共有%d行 %d列小塊" % (rows,cols))
print("每一小塊寬高: %dx%d" % (w, h))
#影象太小則退出
if cols > W or rows > H:
print("影象太小不足分割!(提高影象解析度或降低精細度)")
exit(0)
aimg = []#文字圖形儲存到列表中
#逐個小塊匹配ASCII
for j in range(rows):
y1 = int(j * h)#小塊開始的y座標
y2 = int((j + 1) * h)#小塊結束的y座標
if j == rows - 1:
y2 = H#最後一個小格不夠大,結束y座標用影象高度H表示
aimg.append("")#先插入空串
for i in range(cols):
x1 = int(i * w)#小塊開始的x座標
x2 = int((i + 1) * w)#小塊結束的x座標
if i == cols - 1:
x2 = W#最後一個小格不夠大,結束x座標用影象寬度W表示
img = image.crop((x1, y1, x2, y2))#提取小塊
avg = int(getAverageL(img))#計算平均亮度
if moreLevels:
gsval = gscale1[int((avg * 69) / 255)]#平均亮度值[0,255]對應到十級灰度梯度[0,69],獲得對應ASCII符號
else:
gsval = gscale2[int((avg * 9) / 255)]#平均亮度值[0,255]對應到七十級灰度梯度[0,9],獲得對應ASCII符號
aimg[j] += gsval#更新文字圖形
return aimg
#主函式
def main():
descStr = "Python實現圖片轉ASCII圖形"
parser = argparse.ArgumentParser(description=descStr)
#設定可能的命令列引數來執行程式
parser.add_argument('--file', dest='imgFile', required=True)#必須設定
parser.add_argument('--scale', dest='scale', required=False)#可預設
parser.add_argument('--out', dest='outFile', required=False)
parser.add_argument('--cols', dest='cols', required=False)
parser.add_argument('--morelevels', dest='moreLevels', action='store_true')#設定morelevels為True
args = parser.parse_args()#引數存到args中
imgFile = args.imgFile#輸入的圖片
outFile = 'out.txt'#輸出的ASCII文字圖形
if args.outFile:
outFile = args.outFile
scale = 0.43#垂直比例係數測試得0.43效果佳,必須用等長字型顯示文字,如宋體、Courier
if args.scale:
scale = float(args.scale)
cols = 80#預設分割的列數,列數越大精細度越大,但不建議過大
if args.cols:
cols = int(args.cols)
print("轉換中...")
aimg = covertImageToAscii(imgFile, cols, scale, args.moreLevels)#呼叫匹配函式
f = open(outFile, 'w')#儲存文件圖片
for row in aimg:
f.write(row + '\n')
f.close()
print("ASCII文字圖形儲存於%s" % outFile)
#main函式
if __name__ == '__main__':
main()
#Pycharm設定命令列引數執行方法:Run→Run→Edit Configurations→Defaults→Python→右邊的Parameters
#必填:輸入圖片路徑--file test.jpg
#選填:
#(推薦)圖片分割小塊列數--cols 100
#輸出ASCII文字圖形路徑--out out.txt
#垂直比例係數--scale 1
#使用70級灰度梯度--morelevels