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(): 2 gif = Image.open(gifpath) 3 try: 4 while True: 5 current = gif.tell() 6 gif.save(saveFloder + "/%d.png" % current) 7 gif.seek(current + 1) 8 except: 9 pass
方式2,使用Image
1 def Gif2Png_2(): 2 try: 3 im = Image.open(gifpath) 4 except IOError: 5 print ("Cant load", gifpath) 6 sys.exit(1) 7 i = 0 8 mypalette = im.getpalette() 9 10 try: 11 while 1: 12 im.putpalette(mypalette) 13 frame = im.convert('RGBA') 14 new_im = Image.new("RGBA", im.size) 15 #new_im.paste(im) 16 new_im.paste(frame) 17 new_im.save(saveFloder + "\\%d.png" % i) 18 19 i += 1 20 im.seek(im.tell() + 1) 21 22 except EOFError: 23 pass # end of sequence
方式3
1 #使用imageio處理gif圖 2 def Gif2Png_3(): 3 images = imageio.mimread(gifpath) 4 #把上面的每幀圖片進行儲存 5 for i, img in enumerate(images): 6 img = np.asarray(img) 7 imageio.imwrite(saveFloder + "\\%d.png" % i, img)
生成png效果如下圖所示
2、把圖片處理成gif圖,以下是處理的兩種方式
方式1
1 def Png2Gif(): 2 fileOrder = sorted([int(os.path.splitext(x)[0]) for x in os.listdir(savePath)]) 3 frames = [] 4 for order in fileOrder: 5 filename = str(order)+ '.png' 6 filePath = savePath + "/" + filename 7 frames.append(imageio.imread(filePath)) 8 9 imageio.mimsave(newFilePath, frames, 'GIF', duration = 0.1)
方式2
1 def Png2Gif_2(): 2 fileOrder = sorted([int(os.path.splitext(x)[0]) for x in os.listdir(savePath)]) 3 filenames = [] # 儲存所需要讀取的圖片名稱 4 for order in fileOrder: 5 filename = str(order)+ '.png' 6 filePath = savePath + "/" + filename 7 filenames.append(filePath) # 將使用的讀取圖片彙總 8 9 frames = [] 10 for image_name in filenames: # 索引各自目錄 11 im = Image.open(image_name) # 將圖片開啟,本文圖片讀取的結果是RGBA格式,如果直接讀取的RGB則不需要下面那一步 12 im = im.convert("RGB") # 通過convert將RGBA格式轉化為RGB格式,以便後續處理 13 im = np.array(im) # im還不是陣列格式,通過此方法將im轉化為陣列 14 frames.append(im) # 批量化 15 writeGif(newFilePath, frames, duration=0.1, subRectangles=False) # 生成GIF,其中durantion是延遲,這裡是1ms
五、處理動態圖片
生成字元版gif圖時,如果把拆分開來的圖片先進行儲存硬碟,然後在進行圖片處理在合成最終gif效率會比較慢,因此我們把整個過程都放在內容中處理,即拆分開來的png圖片不進行存檔,而是直接處理,然後在合成gif圖
1 def Gif2Gif(gifpath): 2 A = [] 3 images = imageio.mimread(gifpath) 4 #把上面的每幀圖片進行儲存 5 for img in images: 6 u, v, channels = img.shape 7 c = img * 0 + 255 8 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 9 for i in range(0, u, 6): 10 for j in range(0, v, 6): 11 pix = gray[i, j] 12 b, g, r, a = img[i, j] 13 zifu = string[int(((len(string) - 1) * pix) / 256)] 14 if a != 0: 15 cv2.putText(c, zifu, (j, i), cv2.FONT_HERSHEY_COMPLEX, 0.3, (int(b), int(g), int(r), int(a))) 16 17 A.append(c) 18 19 oldFileName = os.path.splitext(os.path.basename(gifpath))[0] 20 newFilePath = os.getcwd() + '/{}/'.format(saveFloder) + oldFileName +"_new.gif" 21 imageio.mimsave(newFilePath, A, 'GIF', duration=0.1)
原始碼中是支援批量生成字元版gif圖,測試生成效果如下圖所示,左側是原始圖,右側是生成的效果圖
六、字元版動態二維碼
有了普通的gif圖生成動態二維碼的方式,字元版gif圖也就順理成章的可以。
測試生成效果如下圖所示,左側是原始圖,右側是生成的效果圖
七、原始碼下載
需要全部程式碼的到csdn直接下載:Python-字元版gif圖
轉載宣告:本站文章無特別說明,皆為原創,版權所有,轉載請註明:朝十晚八