1. 程式人生 > >Python-字元版gif圖

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圖

 

轉載宣告:本站文章無特別說明,皆為原創,版權所有,轉載請註明:朝十晚八