如何用python繪製一系列三維的逗比風格表情包

  • 2019 年 10 月 6 日
  • 筆記

文章轉載自公眾號

Python愛好者社區 , 作者 盛光曉

表情包是當代社交生態中的戰略性武器,既托起了友情的小船,又浮起了愛情的巨輪,還載起了親情的航空母艦。在一個又一個寧靜又不乏躁動的夜晚,此起彼伏的「老鐵666」、「頂你上去」掀起了一陣又一陣的波瀾。當你和別人斗圖斗得天昏地暗、地動山搖的時候,你有沒有想過,如果有一個三維的逗比表情包,你就可以對別人進行360度的全方位無死角嘲諷了!想到這裡,你是不是由衷地在心裡發出了豪爽而邪惡的笑聲?

就像這樣:

而現在,python就可以滿足你這一不可告人的願望!照例,我們用到的還是matplotlib的三維渲染。

首先,我們要有一張表情包的圖片,最好是長度是寬度的兩倍,這樣的話,平面圖片映射到球體上以後,變形會相對小一些。如果原始圖片不符合要求,可以在畫圖工具裡面重新調整大小,像下圖這樣:

那麼,首先,表情包原圖是這樣的:

然後,我們重新生成一張長圖,長度是上圖的六倍,將上圖的表情橫著擺6個,程式碼和圖片如下:

im=Image.open(r'origin.png')     width,height=im.size     result=Image.new(im.mode,(width*6,height))  for i in range(6):              result.paste(im,box=(i*width,0))     result.save('result.png')

接著,就是確定圖片的顯示範圍,為了避免圖片發生嚴重的變形,需要將圖片映射到「低緯度」地區,我設定的是-pi/8到pi/8的範圍。

用下面幾行程式碼確定所有點的坐標:

#1128指的是長圖的長度  u = np.linspace(0, 2*pi, 1128 * 1)  #94指的是長圖的寬度  v = np.linspace(-pi / 8, pi / 8, 94 * 1)      x=a*np.outer(np.cos(u),np.cos(v))  y=a*np.outer(np.sin(u),np.cos(v))  z=b*np.outer(np.ones(np.size(u)),np.sin(v))

下文的最終繪製過程中,我們需要用到plot_surface函數,而該函數中有一個參數是facecolors,這個參數的意思就是為橢球的表面設置RGB值,我們就要在圖片的各個像素點的RGB值和橢球表面的點之間建立一一對應的關係。程式碼如下:

bm=Image.open(r'result.png')  bm=np.array(bm)      colors=[]      for i in range(bm.shape[1]-1,-1,-1):      item=[]  for j in range(bm.shape[0]-1,-1,-1):          color="#{}{}{}".format(str.zfill(str(hex(bm[j][i][0]))[2:],2),str.zfill(str(hex(bm[j][i][1]))[2:],2),str.zfill(str(hex(bm[j][i][2]))[2:],2))          item.append(color)      colors.append(item)

最後,colors數組裡面存儲了所有橢球上面的點的RGB值。將colors賦值給facecolors就可以完成最後的繪製。

最終的結果大概是這樣:

其他的表情也都可以試試。

說不定會有意外驚喜的喲