Python-字元版gif圖
一、背景
上一篇文章我們講了怎麼做自己的炫酷二維碼,需要的移駕Python-炫酷二維碼,本片文章我們講述下怎麼把一張圖片處理成字元版圖片,就是說使用字元替代每個畫素的顏色,形成一個由字元組成的圖片,並且字元的顏色是由原始的圖片畫素顏色決定
二、準備環境
對圖片的操作我們可以使用PIL、imageio和image2gif庫,處理畫素我們選擇使用opencv-python這個庫。NumPy是Python語言的一個擴充套件程式庫,支援大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式庫。因此我們需要安裝以下幾個包:PIL、imageio、numpy、cv2、images2gif
1 pip install pillow 2 pip install imageio 3 pip install numpy 4 pip install opencv-python 5 pip install images2gif
以上擴充套件包安裝時應該都可以順利安裝,但使用的時候有幾個坑
1、匯入cv2時,如果發生找不到dll的情況,大多數的原因都是當前的python版本和opencv版本不匹配,pip安裝時預設選擇了最新的版本,因此我們安裝時需要 指定安裝的版本pip install opencv-python==3.4.1.15
2、使用images2gif這個庫時,可能會出現無法匯入writeGif介面的情況這個時候需要改下原始碼,把images2gif.py檔案中的兩個from 後邊加上英文點號,修改如下
1 from .images2gif import readGif as readGif 2 from .images2gif import writeGif as writeGif
三、字元版動態圖
首先我們需要搞清楚gif是個什麼玩意兒,其實gif是將多幅影象儲存為一個影象檔案,從而形成動畫,最常見的就是通過一幀幀的動畫串聯起來的搞笑gif圖,所以歸根到底gif仍然是圖片檔案格式。
什麼?原來gif就是一幀一幀的圖片,那麼字元版動態圖其實也就是字元版圖片的連續播放,思考到這兒,我們有了如下思路:
1、拿到一張gif圖
2、把fig圖拆分成多張png圖片,或者其他格式的圖片
3、迴圈遍歷拆分後的圖片,並處理成字元版圖片
4、把處理後的字元版圖片在連線成一個guf檔案
5、儲存gif檔案
通過以上5個步驟,我們即可實現我們的需求,是不是很簡單,下邊我們分佈來講解實現過程
四、gif和png轉換
1、要想獲得靜態圖片,我們需要有一個gif圖,然後把gif圖拆分成多張png圖片,以下是3中處理gif圖片的方式
方式1,使用Image
1 def Gif2Png(): 2gif = Image.open(gifpath) 3try: 4while True: 5current = gif.tell() 6gif.save(saveFloder + "/%d.png" % current) 7gif.seek(current + 1) 8except: 9pass
方式2,使用Image
1 def Gif2Png_2(): 2try: 3im = Image.open(gifpath) 4except IOError: 5print ("Cant load", gifpath) 6sys.exit(1) 7i = 0 8mypalette = im.getpalette() 9 10try: 11while 1: 12im.putpalette(mypalette) 13frame = im.convert('RGBA') 14new_im = Image.new("RGBA", im.size) 15#new_im.paste(im) 16new_im.paste(frame) 17new_im.save(saveFloder + "\\%d.png" % i) 18 19i += 1 20im.seek(im.tell() + 1) 21 22except EOFError: 23pass # end of sequence
方式3
1 #使用imageio處理gif圖 2 def Gif2Png_3(): 3images = imageio.mimread(gifpath) 4#把上面的每幀圖片進行儲存 5for i, img in enumerate(images): 6img = np.asarray(img) 7imageio.imwrite(saveFloder + "\\%d.png" % i, img)
生成png效果如下圖所示
2、把圖片處理成gif圖,以下是處理的兩種方式
方式1
1 def Png2Gif(): 2fileOrder = sorted([int(os.path.splitext(x)[0]) for x in os.listdir(savePath)]) 3frames = [] 4for order in fileOrder: 5filename = str(order)+ '.png' 6filePath = savePath + "/" + filename 7frames.append(imageio.imread(filePath)) 8 9imageio.mimsave(newFilePath, frames, 'GIF', duration = 0.1)
方式2
1 def Png2Gif_2(): 2fileOrder = sorted([int(os.path.splitext(x)[0]) for x in os.listdir(savePath)]) 3filenames = []# 儲存所需要讀取的圖片名稱 4for order in fileOrder: 5filename = str(order)+ '.png' 6filePath = savePath + "/" + filename 7filenames.append(filePath)# 將使用的讀取圖片彙總 8 9frames = [] 10for image_name in filenames:# 索引各自目錄 11im = Image.open(image_name)# 將圖片開啟,本文圖片讀取的結果是RGBA格式,如果直接讀取的RGB則不需要下面那一步 12im = im.convert("RGB")# 通過convert將RGBA格式轉化為RGB格式,以便後續處理 13im = np.array(im)# im還不是陣列格式,通過此方法將im轉化為陣列 14frames.append(im)# 批量化 15writeGif(newFilePath, frames, duration=0.1, subRectangles=False) # 生成GIF,其中durantion是延遲,這裡是1ms
五、處理動態圖片
生成字元版gif圖時,如果把拆分開來的圖片先進行儲存硬碟,然後在進行圖片處理在合成最終gif效率會比較慢,因此我們把整個過程都放在內容中處理,即拆分開來的png圖片不進行存檔,而是直接處理,然後在合成gif圖
1 def Gif2Gif(gifpath): 2A = [] 3images = imageio.mimread(gifpath) 4#把上面的每幀圖片進行儲存 5for img in images: 6u, v, channels = img.shape 7c = img * 0 + 255 8gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 9for i in range(0, u, 6): 10for j in range(0, v, 6): 11pix = gray[i, j] 12b, g, r, a = img[i, j] 13zifu = string[int(((len(string) - 1) * pix) / 256)] 14if a != 0: 15cv2.putText(c, zifu, (j, i), cv2.FONT_HERSHEY_COMPLEX, 0.3, (int(b), int(g), int(r), int(a))) 16 17A.append(c) 18 19oldFileName = os.path.splitext(os.path.basename(gifpath))[0] 20newFilePath = os.getcwd() + '/{}/'.format(saveFloder) + oldFileName +"_new.gif" 21imageio.mimsave(newFilePath, A, 'GIF', duration=0.1)
原始碼中是支援批量生成字元版gif圖,測試生成效果如下圖所示,左側是原始圖,右側是生成的效果圖
六、字元版動態二維碼
有了普通的gif圖生成動態二維碼的方式,字元版gif圖也就順理成章的可以。
測試生成效果如下圖所示,左側是原始圖,右側是生成的效果圖
七、原始碼下載
需要全部程式碼的到csdn直接下載: ofollow,noindex">Python-字元版gif圖
轉載宣告:本站文章無特別說明,皆為原創,版權所有,轉載請註明:朝十晚八