Python 實現圖片轉字符畫,靜態圖、GIF 都能轉

2021-01-20 Python技術

文 | 野客

來源:Python 技術「ID: pythonall」

字符畫是一種由字母、標點或其他字符組成的圖畫,它產生於網際網路時代,在聊天軟體中使用較多,本文我們看一下如何將自己喜歡的圖片轉成字符畫。

靜態圖片

首先,我們來演示將靜態圖片轉為字符畫,功能實現主要用到的 Python 庫為 OpenCV,安裝使用 pip install opencv-python 命令即可。

功能實現的基本思路為:利用聚類將像素信息聚為 3 或 5 類,顏色最深的一類用數字密集度表示,陰影的一類用橫槓(-)表示,明亮部分用空白表示。

主要代碼實現如下:

def img2strimg(frame, K=5):   
    if type(frame) != np.ndarray:
        frame = np.array(frame)
    height, width, *_ = frame.shape  
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame_array = np.float32(frame_gray.reshape(-1))
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    flags = cv2.KMEANS_RANDOM_CENTERS
    # 得到 labels(類別)、centroids(矩心)
    compactness, labels, centroids = cv2.kmeans(frame_array, K, None, criteria, 10, flags)
    centroids = np.uint8(centroids)
    # labels 的數個矩心以隨機順序排列,所以需要簡單處理矩心
    centroids = centroids.flatten()
    centroids_sorted = sorted(centroids)
    # 獲得不同 centroids 的明暗程度,0 為最暗
    centroids_index = np.array([centroids_sorted.index(value) for value in centroids])
    bright = [abs((3 * i - 2 * K) / (3 * K)) for i in range(1, 1 + K)]
    bright_bound = bright.index(np.min(bright))
    shadow = [abs((3 * i - K) / (3 * K)) for i in range(1, 1 + K)]
    shadow_bound = shadow.index(np.min(shadow))
    labels = labels.flatten()
    # 將 labels 轉變為實際的明暗程度列表
    labels = centroids_index[labels]
    # 解析列表
    labels_picked = [labels[rows * width:(rows + 1) * width:2] for rows in range(0, height, 2)]
    canvas = np.zeros((3 * height, 3 * width, 3), np.uint8)
 # 創建長寬為原圖三倍的白色畫布
    canvas.fill(255)
    y = 8
    for rows in labels_picked:
        x = 0
        for cols in rows:
            if cols <= shadow_bound:
                cv2.putText(canvas, str(random.randint(2, 9)),
                            (x, y), cv2.FONT_HERSHEY_PLAIN, 0.45, 1)
            elif cols <= bright_bound:
                cv2.putText(canvas, "-", (x, y),
                            cv2.FONT_HERSHEY_PLAIN, 0.4, 0, 1)
            x += 6
        y += 6
    return canvas

原圖如下:

效果圖如下:

GIF 動圖

接下來我們演示將 GIF 轉為字符畫,功能實現主要用到的 Python 庫為 imageio、Pillow,安裝使用 pip install imageio/Pillow 命令即可。

功能實現的基本思路如下:

主要代碼實現如下:

# 拆分 gif 將每一幀處理成字符畫
def gif2pic(file, ascii_chars, isgray, font, scale):
    '''
    file: gif 文件
    ascii_chars: 灰度值對應的字符串
    isgray: 是否黑白
    font: ImageFont 對象
    scale: 縮放比例
    '''
    im = Image.open(file)
    path = os.getcwd()
    if(not os.path.exists(path+"/tmp")):
        os.mkdir(path+"/tmp")
    os.chdir(path+"/tmp")
    # 清空 tmp 目錄下內容
    for f in os.listdir(path+"/tmp"):
        os.remove(f)
    try:
        while 1:
            current = im.tell()
            name = file.split('.')[0]+'_tmp_'+str(current)+'.png'
            # 保存每一幀圖片
            im.save(name)
            # 將每一幀處理為字符畫
            img2ascii(name, ascii_chars, isgray, font, scale)
            # 繼續處理下一幀
            im.seek(current+1)
    except:
        os.chdir(path)

# 將不同的灰度值映射為 ASCII 字符
def get_char(ascii_chars, r, g, b):
    length = len(ascii_chars)
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
    return ascii_chars[int(gray/(256/length))]


# 將圖片處理成字符畫
def img2ascii(img, ascii_chars, isgray, font, scale):
    scale = scale
    # 將圖片轉換為 RGB 模式
    im = Image.open(img).convert('RGB')
    # 設定處理後的字符畫大小
    raw_width = int(im.width * scale)
    raw_height = int(im.height * scale)
    # 獲取設定的字體的尺寸
    font_x, font_y = font.getsize(' ')
    # 確定單元的大小
    block_x = int(font_x * scale)
    block_y = int(font_y * scale)
    # 確定長寬各有幾個單元
    w = int(raw_width/block_x)
    h = int(raw_height/block_y)
    # 將每個單元縮小為一個像素
    im = im.resize((w, h), Image.NEAREST)
    # txts 和 colors 分別存儲對應塊的 ASCII 字符和 RGB 值
    txts = []
    colors = []
    for i in range(h):
        line = ''
        lineColor = []
        for j in range(w):
            pixel = im.getpixel((j, i))
            lineColor.append((pixel[0], pixel[1], pixel[2]))
            line += get_char(ascii_chars, pixel[0], pixel[1], pixel[2])
        txts.append(line)
        colors.append(lineColor)
    # 創建新畫布
    img_txt = Image.new('RGB', (raw_width, raw_height), (255, 255, 255))
    # 創建 ImageDraw 對象以寫入 ASCII
    draw = ImageDraw.Draw(img_txt)
    for j in range(len(txts)):
        for i in range(len(txts[0])):
            if isgray:
                draw.text((i * block_x, j * block_y), txts[j][i], (119,136,153))
            else:
                draw.text((i * block_x, j * block_y), txts[j][i], colors[j][i])
    img_txt.save(img)

# 讀取 tmp 目錄下文件合成 gif
def pic2gif(dir_name, out_name, duration):
    path = os.getcwd()
    os.chdir(dir_name)
    dirs = os.listdir()
    images = []
    num = 0
    for d in dirs:
        images.append(imageio.imread(d))
        num += 1
    os.chdir(path)
    imageio.mimsave(out_name + '_ascii.gif',images,duration = duration)

原圖如下:

黑白效果圖如下:

彩色效果圖如下:

總結

本文我們利用 Python 演示了將靜態圖和 GIF 轉為字符畫的方法,大家如果有興趣的話,可以將自己喜歡的圖轉一下,如果對轉換效果不滿意,還可以修改代碼,改成自己滿意的效果。

PS:公號內回復「Python」即可進入Python 新手學習交流群,一起 100 天計劃!


老規矩,兄弟們還記得麼,右下角的 「在看」 點一下,如果感覺文章內容不錯的話,記得分享朋友圈讓更多的人知道!

代碼獲取方式

相關焦點

  • 圖片轉字符畫
    運行平臺: Windows  Python版本: Python3.6  IDE: Sublime Text一、實驗原理字符畫是一系列字符的組合,我們可以把字符看作是比較大塊的像素,一個字符能表現一種顏色(暫且這麼理解吧),字符的種類越多,可以表現的顏色也越多,圖片也會更有層次感。
  • 用Python把圖片轉成字符畫
    剛學會上網的時候,看到上面的圖覺得老神奇了。普通的英文字母居然可以畫畫。自己畫是肯定看不出的。然而幼稚的我們被騙了原圖是這樣的通過下面的代碼生成了字符畫,什麼原理呢?那我們反轉過來,把彩色圖片轉成灰度圖,再用ascii映射到灰度值上,就可以顯示出肉眼可以接受的信息了。用Python完全可以做到在image2ascii方法裡,我們用thumbnail函數改變源圖片的尺寸為寬與高為100,然後用convert轉為灰度圖片。
  • 從動圖中導出圖片GIF轉幀圖片的方法
    大家平時肯定會遇到一些有趣的GIF動圖,這種動態圖片是由很多靜態的圖片組合處理而成的,將它放到gif製作工具上看,就能看到一幀幀靜態圖片。網上不乏有意思的GIF動畫內容,如果想要提取動圖中的其中一幀圖片,應該如何實現呢?
  • 視頻轉gif:在線視頻轉gif動態圖片的方法
    有的時候我們想要將視頻轉換成gif動圖,但是視頻轉動態圖片怎麼轉?方法很簡單,在線幾步輕鬆完成!這也是小編今天才發現的一個方法,使用到的工具是迅捷pdf在線轉換器,只需要簡單的幾步就可以將視頻轉gif,話不多說,下面將詳細的步驟分享給大家。
  • Android 實現 視頻 轉 字符畫效果
    上一篇文章我們講到圖片轉字符畫,這篇文章要實現 視頻 轉 字符畫效果。我們看一下實現出來的效果圖:效果圖有點糊,原文的效果圖會更好實現的效果還是讓人挺滿意的。YUV下也分不同的格式分別有:Y'UV, YUV, YCbCr,YPbPr等,安卓設備因為 API 21 統一的原因都能使用 COLOR_FormatYUV420Flexible 格式,使得 MediaCodec 的所有硬體解碼都支持這種格式。
  • mp4轉gif可以嗎?怎麼把視頻轉成動圖?
    乍一看,gif和MP4文件還挺像的,都是以動畫的形式來呈現的,但是實際上,兩種文件之間卻有很大的不同之處,gif再怎麼會動也是一張圖片,而MP4則終究是視頻。如此大的區別,那麼gif和MP4是不是永遠都沒辦法畫上一個等號呢?
  • 視頻轉gif動態圖格式如何操作
    gif是一種圖片格式,相比其它圖片而言,gif的特殊之處在於這是一種會「動」的圖片格式。我們使用社交軟體時經常會發送gif表情包增添樂趣,gif動圖表情包相比傳統的靜態表情包而言,表達效果更加強烈、明顯。於是乎就有不少小夥伴想要把一些有趣的視頻片段轉換成gif動態圖格式。
  • Python:製作動態字符圖
    ^▽^)這裡就不必多說了,也就導入幾個用到的包SOURCE_PATH:這個是GIF的路徑OUTPUT_PATH:這個是每一幀的存放路徑FRAMES_PATH:這個也是每一幀的存放路徑,不過是已轉為字符畫的圖片create_dir() 方法只是用來創建文件夾的,若是存在那便會刪掉裡面的內容
  • 視頻如何轉gif圖片?在線視頻GIF生成的操作方法
    在日常生活中,每天都會看到許多不同類型的視頻,那麼如果想將這些視頻轉換成gif圖片的話,怎樣才能快速完成視頻轉gif操作呢?下面給大家分享一下款gif動畫在線製作工具,在線製作動態圖片,通過簡單的操作步驟,就能夠將視頻快速轉換為gif動圖,以下為小編給大家分享的使用方法,快來看一下如何操作吧。點擊導航欄中的gif工具,選擇視頻轉gif功能。點擊選擇視頻,將想要截取片段的視頻上傳到網站。
  • 如何在線將靜態圖片與gif動圖合成一張新的動圖?
    動圖是常用的一種圖片展現方式,一般在聊天或者公眾號推文中經常會看到,可以下載保存下來自己使用,那麼如果想要在gif動圖的基礎上添加靜態圖片,怎樣才能將靜態圖片和gif動圖合成一張動圖該如何來進行操作呢?
  • 視頻如何轉GIF?簡單幾步,自己也能製作動圖!
    我們總能在網上看到一些非常有趣的動態圖片,讓人啼笑皆非。那這樣的動圖是怎麼做出來的呢?其實這些有大部分是視頻做成的gif圖片,那麼視頻如何轉gif圖片呢?小編教你一招!準備:電腦風雲視頻轉換器具體步驟:第一步:安裝好風雲視頻轉換器之後,我們點擊主界面上的「視頻轉GIF」,進入操作界面後,點擊「添加文件」,將文件添加進入等待處理。
  • 視頻文件怎麼轉換成gif動態圖?教你兩種快速將視頻轉gif的方法
    視頻文件怎麼轉換成gif動態圖?gif動態圖作為表情包的其中一種,相比傳統靜態表情包有更加生動形象的表達效果。然而在平時看電影或電視劇想將視頻中有趣的橋段製作成gif動態圖時該怎麼辦呢?接下來小編使用兩種方式將已有的視頻轉換成gif格式。
  • 視頻轉gif,gif合成,gif剪輯,只要一招都搞定!
    在公眾號文章中使用動圖已經是大勢所趨,不管是哪一篇文章多多少少都會有動圖的身影,有的是從視頻中截取的,有的是自己合成製作的,還有的是剪輯出來的,只要能夠契合文章的內容,就能讓文章增色不少,看起來也會輕鬆一些。那麼視頻轉gif,圖片合成gif,gif剪輯是不是非常麻煩呢?
  • 視頻轉gif怎麼轉?把視頻轉換成動態圖表情包的方法
    視頻轉gif怎麼轉?相信很多小夥伴在利用社交軟體聊天的時候都喜歡發送一些gif動態圖給對方為聊天增加些許樂趣,除此之外有趣的gif動態圖表情包也能在短時間之內迅速傳播讓人記憶深刻。那你知道怎麼把視頻轉gif把視頻中比較有趣的片段提取出來呢?
  • 動態圖怎麼製作?簡單幾步教你把mp4轉gif
    怎麼把mp4轉gif製作動圖?想必很多小夥伴對於gif都不會陌生,這是一個常見的圖片格式,但它和別的圖片不同的地方在於gif是一種會動的圖片格式-動態圖。隨著網絡流行語的不斷增多,不少小夥伴喜歡在聊天時發送一些gif動態表情包增添樂趣。那你知道如何把mp4轉gif製作表情包嗎?
  • 視頻轉GIF怎麼轉?有什麼軟體可以將視頻轉成動圖嗎?
    現在的聊天內容,可真叫一個豐富多彩,咱們除了會發文字、發語音、發圖之外,也會用gif來鬥圖,有的gif是來自於網絡的,但是有的gif,可就是咱們自己做出來的。說到這裡,小芹今天就要來為大家分享一個小技巧了,你知道視頻轉GIF怎麼轉?有什麼軟體可以將視頻轉成動圖嗎?如果你也對製作gif有興趣的話,不妨看看接下來的內容吧!
  • [視頻] Plotagraph Pro: 這款工具能將靜態圖像轉成流動的GIF圖片
    但是對於抓拍來的靜態圖像,其實我們也有方法讓它「流動」起來,這就是Plotagraph Pro派上用場的時候了。作為一款強大的新式圖像工具,它由藝術家兼攝影師Troy Plota打造。更棒的是,我們在web上就能直接操作。
  • 視頻怎麼轉gif動畫?這款軟體很6,一鍵免費製作高級動圖
    視頻怎麼轉gif動畫?從事創意內容運營的小夥伴們應該知道,與冗長的視頻相比較,gif動畫更能吸引到人們的目光。迅捷視頻轉換器功能多樣,可以一鍵免費製作出高級gif動圖。想要get到視頻轉gif技能的話,接著往下看,大家便能找到滿意的答案哦。在軟體首頁選擇【視頻轉gif】功能以後,進入相應操作頁面。頁面左邊的功能分類欄,大家可以隨時選擇需要的視頻轉換、編輯功能。頁面右邊是文件添加區,點擊相應按鈕便可把需要轉換為gif動態圖片的視頻文件添加進來。
  • python 人像轉漫畫
    在網上,以及一些視頻軟體裡面,我們都可以看見將人像轉變為漫畫的軟體,那我們可不可以自己來做一個呢!那還等什麼,來看一看吧#python#材料準備按照我們之前的操作,我們都是需要先準備材料。思路分析實現,我們需要人像轉漫畫,似乎我們自己寫一個,以目前的能力來說,還不太現實,那我們只能去掉調用比人的了。經過查找材料,以及確定範圍,於是,找到了比較好的方案。1、我們調用某度的ai接口。接口需要進行加密,以及ak和sk。
  • 如何在蘋果電腦上完成圖片轉PDF?分享兩種圖片轉PDF的方法
    常見圖片格式:jpg、png 、gif、bmp「JPG」格式JPG格式,也叫做JPEG格式,是常用的一種圖片文件格式。一般我們在存儲圖片時,是顯示的JPEG格式,大部分手機拍攝出來的照片是JPE格式的。