pygame和PIL模塊實現文字圖片化
text="任何屁話,\n只要被打印出來\n就成了真理"
使用PIL模塊
廖雪峰的網站上有PIL的使用教程,但是他的安裝地址是直接引到PIL的官方網站的。查看了PIL的官網,發現官方支持好像僅僅做到了python2.7的部分。所以我在pycharm上面搜索到了適配python3.x的包,他好像改叫Pillow。他們的歷史淵源(pillow是PIL的一個派生分支,現在發展的更好)我就不去考慮了,但是他的加載還是和PIL完全一樣的,包括內部模塊的加載,幾乎沒有區別。
- 安裝:
pip install Pillow
使用PIL將文字轉化為圖片
真實的過程是:現在內存中生成一張圖片,將需要的文字繪制到這個圖片上,再將圖片保存到指定位置
import os
import Image,ImageDraw,ImageFont,ImageFilter
import random
BASE_DIR=os.path.dirname(os.getcwd())
text="任何屁話,\n只要被打印出來\n就成了真理"
# PIL實現
width=60*4
height=60*2
im=Image.new('RGB',(width,height),(255,255,255))
dr=ImageDraw.Draw(im)
font=ImageFont.truetype(os.path.join('fonts',BASE_DIR+"\\resources\\minijson.ttf"),20)
dr.text((10,5),text,font=font,fill='#000000')
im.show()
im.save("t.png")
在我看的教程中,PIL還是那個適配2.7的原生庫,它好像有一個“不能正確處理非ASCII字符的點陣字體的渲染,對於宋體這樣的字體來說,只有>=18px,才會被當做適量字體處理”的bug。
但是因為我使用的是pillow,所以在我的測試中,並沒有出現這種情況。
記得測試一下這個
im.show()
因為我現在不確定這個方法的具體作用是什么
使用pygame將文字轉換為圖片
# pygame實現
import pygame
pygame.init()
font1=pygame.font.Font(os.path.join('fonts',BASE_DIR+"\\resources\\minijson.ttf"),20)
rtext=font1.render(text,True,(0,0,0),(255,255,255))
pygame.image.save(rtext,"f.jpg")
可以發現這種方法和直接用PIL模塊的步驟差異還是不小的。
PIL更像是:設置一塊畫板---->繪制圖案(文字字體)---->生成圖片
pygame則是:設置一個字體---->給設置的字體賦予內容---->將文字生成圖片
生成的效果也是顯而易見的不同。PIL有一塊固定的畫板,這塊畫板不按照字多字少而產生變化,字多他不會跟着長大,字少他也不會適應縮小
但是pygame就不一樣,他好像並沒有按照我設置的換行符\\n
跟着變化,僅僅顯示一行,剛剛好是這行內容的長度。
所以pygame這個font模塊還是需要深入了解一下:
- 如何讓他支持換行?
- 是否支持自定義畫板大小?
- 更高級的,這以上兩種方式,如何支持文本的格式化,支持換行段落排版?
內存內生成圖片的案例
# -*- coding: utf-8 -*-
import os
import StringIO
import Image, ImageFont, ImageDraw
import pygame
pygame.init()
text = u"這是一段測試文本,test 123。"
im = Image.new("RGB", (300, 50), (255, 255, 255))
font = pygame.font.Font(os.path.join("fonts", "simsun.ttc"), 14)
rtext = font.render(text, True, (0, 0, 0), (255, 255, 255))
sio = StringIO.StringIO()
pygame.image.save(rtext, sio)
sio.seek(0)
line = Image.open(sio)
im.paste(line, (10, 5))
im.show()
im.save("c.png")
將文字先用pygame渲染成圖片,將渲染結果保存在一個stringIO對象中,然后再用PIL加載他。使用stringIO的好處是,一切操作都是在內存中進行的,不需要先將它保存到硬盤(考慮到硬盤IO和內存IO的性能差異)。