亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python使用PIL將圖片或GIF轉(zhuǎn)為字符畫的方法詳解

 更新時間:2025年03月20日 08:27:39   作者:李恩澤的博客  
PIL是專為Python語言設(shè)計的圖像處理庫,它涵蓋了廣泛的圖像處理功能,如圖像的加載、保存、編輯,以及執(zhí)行多樣化的圖像處理任務(wù),本文給大家介紹了Python使用PIL將圖片或GIF轉(zhuǎn)為字符畫的方法,需要的朋友可以參考下

圖片或GIF轉(zhuǎn)字符畫

紅及一時的編程小玩具,將圖片轉(zhuǎn)為字符畫

接下來通過Python實現(xiàn),比較好玩

圖片轉(zhuǎn)換為黑白字符畫

  • 安裝pillow
pip3 install pillow

灰度值:黑白圖像中點的顏色深度,范圍一般從0~255,白色為255,黑色為0,所以黑白圖片也被成為灰度圖像

  • RBG映射灰度公式

我們要將一張圖片的灰度處理,將其中的色彩處理為黑白灰亮度圖像

越亮的地方用占位百分比越小的字符來替換處理,比如|

而越暗的地方用占位百分比越大的字符來替換處理,比如#

  • 創(chuàng)建一個不重復(fù)字符序列數(shù)據(jù),灰度值越小(越暗)為序列數(shù)據(jù)開頭,越大(越亮)到序列結(jié)尾,長度為90,用來映射256個灰度值,便捷的方法可以直接使用ascii碼進行構(gòu)建

  • 定義函數(shù),用來處理RGB并得出灰度值,根據(jù)灰度值,得出一個字符

char_=list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?_+~<>i!lI;:,\"^`'. ")
def get_char(r,g,b, alpha=256):
	'''
		r(紅),g(綠),b(藍)
		total: 灰度值總大小 
		return -> str
	'''
	if alpha == 0:
		return ' '
	gray = 0.2126 * r  + 0.7152 * g + 0.0722 * b #得出灰度值
	char_length = len(char_) #字符序列長度
	index = (alpha+1) / char_length #總灰度值對應(yīng)列表索引范圍
	return char_[int(gray/index)] #返回當(dāng)前灰度值所對應(yīng)字符
  • pillow模塊可以打卡圖像,并重設(shè)圖像大小,分析圖像像素,定義如下函數(shù),取出圖像對應(yīng)坐標(biāo)像素
from PIL import Image
def convert_image_to_ascii(origin_path, output_path, width=150, height=80):
    """
    將圖像轉(zhuǎn)換為ASCII文字并保存到文本文件
    :param origin_path: 輸入圖像路徑
    :param output_path: 輸出文本文件路徑
    :param width: 輸出寬度
    :param height: 輸出高度
    :return: None
    """
    # 打開圖像,并將其轉(zhuǎn)換為RGBA格式以確保包含alpha通道信息
    img = Image.open(origin_path).convert('RGBA')
    
    #Image.NEAREST 代表設(shè)置縮放圖片的質(zhì)量
    img = img.resize((width,height),Image.NEAREST)
 
    #遍歷像素,獲得灰度值對應(yīng)字符
    content = ''
    for h in range(height):
        for w in range(width):
            char = get_char(*img.getpixel((w,h)))
            content += char
        content += '\n' #每一行像素?fù)Q行追加\n
    with open(output_path,'w') as fp:
        fp.write(content)
    return content

  • 運行這段代碼,調(diào)用analy_image函數(shù),傳入待處理圖像路徑path及保存之后的文件路徑file

比如這樣一張圖片

  • 經(jīng)過代碼處理之后將會變?yōu)?/li>

  • 如果想把文本存儲為圖片也可以
from PIL import Image
from PIL import Image, ImageDraw, ImageFont

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


def get_char(r, g, b, alpha=256):
    '''
            r(紅),g(綠),b(藍)
            total: 灰度值總大小 
            return -> str
    '''
    if alpha == 0:
        return ' '
    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b  # 得出灰度值
    char_length = len(char_)  # 字符序列長度
    index = (alpha+1) / char_length  # 總灰度值對應(yīng)列表索引范圍
    return char_[int(gray/index)]  # 返回當(dāng)前灰度值所對應(yīng)字符


def convert_image_to_ascii(origin_path, output_path, width=150, height=80):
    """
    將圖像轉(zhuǎn)換為ASCII文字并保存到文本文件
    :param origin_path: 輸入圖像路徑
    :param output_path: 輸出文本文件路徑
    :param width: 輸出寬度
    :param height: 輸出高度
    :return: None
    """
    # 打開圖像,并將其轉(zhuǎn)換為RGBA格式以確保包含alpha通道信息
    img = Image.open(origin_path).convert('RGBA')
    
    #Image.NEAREST 代表設(shè)置縮放圖片的質(zhì)量
    img = img.resize((width,height),Image.NEAREST)
 
    #遍歷像素,獲得灰度值對應(yīng)字符
    content = ''
    for h in range(height):
        for w in range(width):
            char = get_char(*img.getpixel((w,h)))
            content += char
        content += '\n' #每一行像素?fù)Q行追加\n
    with open(output_path,'w') as fp:
        fp.write(content)
    return content


def ascii_art_to_image(ascii_art, output_path, font_path=None, font_size=20):
    """
    將ASCII字符藝術(shù)轉(zhuǎn)換為圖片并保存
    :param ascii_art: ASCII字符藝術(shù)字符串
    :param output_path: 輸出圖片路徑
    :param font_path: 字體文件路徑,默認(rèn)為None,表示使用默認(rèn)字體
    :param font_size: 字體大小
    :return: None
    """
    # 分割A(yù)SCII藝術(shù)字符串為行列表
    lines = ascii_art.split('\n')

    # 獲取最長行的長度和總行數(shù),用于確定圖片尺寸
    max_line_length = max(len(line) for line in lines)
    num_lines = len(lines)

    # 設(shè)置圖片的基本參數(shù)
    char_width, char_height = font_size, font_size  # 假設(shè)每個字符寬度和高度相等
    margin = 10  # 圖片邊緣留白

    # 創(chuàng)建白色背景的新圖像
    image = Image.new('RGB',
                      (max_line_length * char_width + 2 * margin,
                       num_lines * char_height + 2 * margin),
                      color='white')
    draw = ImageDraw.Draw(image)

    try:
        # 加載字體
        if font_path:
            font = ImageFont.truetype(font_path, font_size)
        else:
            font = ImageFont.load_default()
    except IOError:
        print("加載字體失敗,使用默認(rèn)字體")
        font = ImageFont.load_default()

    # 在圖像上繪制ASCII藝術(shù)文字
    for i, line in enumerate(lines):
        draw.text((margin, margin + i * char_height),
                  line, fill='black', font=font)

    # 保存圖像
    image.save(output_path)
    print(f"已保存圖片至 {output_path}")


path = '1.jpg'
file = '1.txt'
content_str = convert_image_to_ascii(path, '1.txt')
ascii_art_to_image(content_str, '1_ASCII.jpg')
  • 完整代碼
from PIL import Image

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


def get_char(r, g, b, alpha=256):
    '''
    r(紅),g(綠),b(藍)
    total: 灰度值總大小 
    return -> str
    '''
    if alpha == 0:
        return ' '
    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b  # 得出灰度值
    char_length = len(char_)  # 字符序列長度
    index = (alpha+1) / char_length  # 總灰度值對應(yīng)列表索引范圍
    return char_[int(gray/index)]  # 返回當(dāng)前灰度值所對應(yīng)字符


def analy_image(path, file):
    """
    path: 處理圖像路徑
    file: 處理后的保存文件
    return -> None
    """
    img = Image.open(path)
    width = 80
    height = 80
    img = img.resize((width, height), Image.NEAREST)
    # Image.NEAREST 代表設(shè)置縮放圖片的質(zhì)量

    # 遍歷像素,獲得灰度值對應(yīng)字符
    content = ''
    for h in range(height):
        for w in range(width):
            char = get_char(*img.getpixel((w, h)))
            # img.getpixel(w,h) 獲取對應(yīng)坐標(biāo)像素
            content += char
        content += '\n'  # 每一行像素?fù)Q行追加\n
    print(content)
    with open(file, 'w') as fp:
        fp.write(content)

將GIF轉(zhuǎn)換為動態(tài)彩色字符畫

思路很簡單,將GIF圖片處理為一幀一幀的單獨圖片,再將單獨圖片灰度處理搞成字符圖片,像上面這樣,最終再上色并且把一陣一陣的字符圖片組合成一個字符GIF

from PIL import Image,ImageDraw,ImageFont
import os
from time import sleep
import imageio

char_ = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
#"MNHQ$OC67+>!:-. "
def get_char(r,g,b,alpha=256):
    '''
    r(紅),g(綠),b(藍)
    total: 灰度值總大小 
    return -> str
    '''
    if alpha == 0:
            return ''
    gray = 0.2126 * r  + 0.7152 * g + 0.0722 * b #得出灰度值
    char_length = len(char_) #字符序列長度
    index = (alpha+1) / char_length #總灰度值對應(yīng)列表索引范圍
    return char_[int(gray/index)] #返回當(dāng)前灰度值所對應(yīng)字符

def gif2png(path='test.gif'):
    '''
    path: GIF 圖像路徑
    該函數(shù)拆分GIF為單獨的每一張PNG圖片
    '''
    img = Image.open(path)
    work_path = os.getcwd() #當(dāng)前工作路徑
    cache_dir = os.path.join(work_path,'cache')
    if not os.path.exists(cache_dir):
        #如果不存在保存單獨每一幀圖片的目錄,則創(chuàng)建該目錄
        os.mkdir(cache_dir)
    while True:
        try:
            current = img.tell() #獲取當(dāng)前幀位置
            file_name = os.path.join(cache_dir,str(current)+'.png')
            img.save(file_name)
            img.seek(current+1) #向下一幀讀取
        except EOFError:
            #GIF讀取完畢
            break
    return current

def analy_image(pic_id):
    """
    path: 處理圖像路徑
    file: 處理后的保存文件
    return -> None
    """
    cache_dir = os.path.join(os.getcwd(),'cache')
    path = os.path.join(cache_dir,'%d.png' % (pic_id))
    img = Image.open(path).convert('RGB')
    #GIF處理后的單幀圖片需要轉(zhuǎn)換為RGB格式,否則會報錯
    pic_width,pic_height = img.width,img.height
    width = int(pic_width / 6)
    height = int(pic_height / 12)
    img = img.resize((width,height),Image.NEAREST)
    #Image.NEAREST 代表設(shè)置縮放圖片的質(zhì)量

    #遍歷像素,獲得灰度值對應(yīng)字符
    content = ''
    colors = []
    for h in range(height):
        for w in range(width):
            px = img.getpixel((w,h))
            char = get_char(px[0],px[1],px[2], px[3] if len(px) > 3 else 256)
            colors.append( (px[0],px[1],px[2]) )
            #img.getpixel(w,h) 獲取對應(yīng)坐標(biāo)像素
            content += char
        content += '\n' #每一行像素?fù)Q行追加\n
        colors.append( (255,255,255) ) 
    print(content)
    return content,colors,pic_width,pic_height

def text2png(content,colors,pic_width,pic_height,pic_id):
    '''
    將輸出的圖片字符文本轉(zhuǎn)換為png
    '''
    work_path = os.getcwd() #當(dāng)前工作路徑
    content_dir = os.path.join(work_path,'content')
    if not os.path.exists(content_dir):
        #如果不存在保存單獨每一幀圖片的目錄,則創(chuàng)建該目錄
        os.mkdir(content_dir)

    txt_img = Image.new("RGB", (pic_width,pic_height), (255,255,255))
    canvas = ImageDraw.Draw(txt_img) #創(chuàng)建一個可以在給定圖像上繪圖的對象
    font = ImageFont.load_default().font

    x = 0
    y = 0

    font_w,font_h =  font.getsize(content[1]) #字體的寬高

    for i in range(len(content)):
        if content[i] == '\n':
            x = -font_w #每次初始化橫縱坐標(biāo)
            y += font_h
        canvas.text( (x,y), content[i], colors[i])
        x += font_w # 追加一個字體的像素
    txt_img.save(os.path.join(content_dir,'%d.png' % (pic_id)))

def png2gif(_id,dir_name='content',duration=5 / 130):
    '''
    將之前處理好的字符png圖片組合成GIF圖像
    通過imageio模塊處理合并
    '''
    path = os.path.join(os.getcwd(),dir_name)
    images = []
    for pic_id in range(_id):
        #遍歷取出每一張?zhí)幚砗蟮淖址麍D片id值
        images.append(imageio.imread(os.path.join(path,'%d.png' % pic_id) ) )
        #從文件中讀入數(shù)據(jù)
    imageio.mimsave(os.path.join(os.getcwd(),'fin.gif'), images, duration=duration)
    #保存路徑、png圖片數(shù)據(jù)列表、合并幀頻率
            
def main():
    path = input(':')
    _id = gif2png(path)
    for pic_id in range(_id+1):
        content,colors,pic_width,pic_height = analy_image(pic_id)
        text2png(content,colors,pic_width,pic_height,pic_id)
        sleep(5 / 130)
        os.system('cls')
    png2gif(_id)

if __name__ == '__main__':
	main()
  • 來看這樣一張GIF圖片

  • 他會變成這樣

以上就是Python使用PIL將圖片或GIF轉(zhuǎn)為字符畫的方法詳解的詳細內(nèi)容,更多關(guān)于Python PIL圖片或GIF轉(zhuǎn)字符畫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python 實現(xiàn)體質(zhì)指數(shù)BMI計算

    python 實現(xiàn)體質(zhì)指數(shù)BMI計算

    這篇文章主要介紹了python 實現(xiàn)體質(zhì)指數(shù)BMI計算操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python如何在一個py文件中獲取另一個py文件中的值(一個或多個)

    python如何在一個py文件中獲取另一個py文件中的值(一個或多個)

    這篇文章主要介紹了python如何在一個py文件中獲取另一個py文件中的值(一個或多個),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • python時間序列數(shù)據(jù)相減的實現(xiàn)

    python時間序列數(shù)據(jù)相減的實現(xiàn)

    本文主要介紹了python時間序列數(shù)據(jù)相減的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 解決每次打開pycharm直接進入項目的問題

    解決每次打開pycharm直接進入項目的問題

    今天小編就為大家分享一篇解決每次打開pycharm直接進入項目的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Python實現(xiàn)制作透明背景的電子印章

    Python實現(xiàn)制作透明背景的電子印章

    這篇文章主要為大家詳細介紹了如何利用Python語言實現(xiàn)制作透明背景的電子印章,文中的示例代碼講解詳細,感興趣的小伙伴可以嘗試一下
    2022-09-09
  • Python中的全局變量如何理解

    Python中的全局變量如何理解

    在本篇文章里小編給大家整理的是關(guān)于Python中全局變量詳解內(nèi)容,需要的朋友們可以參考下。
    2020-06-06
  • 用python做一個搜索引擎(Pylucene)的實例代碼

    用python做一個搜索引擎(Pylucene)的實例代碼

    下面小編就為大家?guī)硪黄胮ython做一個搜索引擎(Pylucene)的實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 基于python分享一款地理數(shù)據(jù)可視化神器keplergl

    基于python分享一款地理數(shù)據(jù)可視化神器keplergl

    這篇文章主要介紹了分享一款地理數(shù)據(jù)可視化神器keplergl,keplergl是由Uber開源的一款地理數(shù)據(jù)可視化工具,通過keplergl我們可以在Jupyter?notebook中使用,下文分享需要的小伙伴可以參考一下
    2022-02-02
  • Python利用os模塊實現(xiàn)自動刪除磁盤文件

    Python利用os模塊實現(xiàn)自動刪除磁盤文件

    你們一定想不到os模塊還可以這樣玩,本文就將利用Python中的os模塊實現(xiàn)自動刪除磁盤文件功能,文中的示例代碼講解詳細,感興趣的可以嘗試一下
    2022-11-11
  • python多線程中獲取函數(shù)返回值的三種方法

    python多線程中獲取函數(shù)返回值的三種方法

    本文主要介紹了python多線程中獲取函數(shù)返回值的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03

最新評論