PythonPIL创建文字图片

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

PIL库中包含了很多模块,恰当地利用这些模块可以做许多图像处理方面的工作。

下面是我用来生成字母或字符串测试图片而写的类及测试代码。

主要用到的模块:PIL.Image,PIL.ImageDraw,PIL.ImageFont

PIL.Image用来生成一个空的图片,ImageDraw用来在空图片上画图及写字符,ImageFont则是创建需要使用到的字体

主要用到的代码:

#创建一个空的图片self.img =Image.new(self.imgMode, self.imgSize, self.bg_color)

self.drawBrush= ImageDraw.Draw(self.img)#创建画刷,用来写文字到图片img上#创建字体,fontFile为字体文件,若非系统字体需加详细路径self.font =ImageFont.truetype(fontFile,fontsize)#使用特定字体写字,(textX0,textY0)为文字开始的左上角起始位置self.drawBrush.text((textX0,textY0), self.letters, fill=self.fg_color,font=self.font)

 

详细代码:

#-*- coding:gb2312 -*-fromPILimportImage,ImageDraw,ImageFont,ImageOpsimportnumpy as npimportrandomclassLetterImage():def__init__(self,fontFile='',imgSize=(0,0),imgMode='RGB',bg_color=(0,0,0),fg_color=(255,255,255),fontsize=20):

self.imgSize=imgSize

self.imgMode=imgMode

self.fontsize=fontsize

self.bg_color=bg_color

self.fg_color=fg_color#self.font = ImageFont.load('车牌字体.ttf')if''==fontFile:

self.font= ImageFont.truetype('DIN1451.ttf', fontsize)else:

self.font=ImageFont.truetype(fontFile,fontsize)defGenLetterImage(self,letters):'''Generate the Image of letters'''self.letters=letters

(self.letterWidth,self.letterHeight)=self.font.getsize(letters)ifself.imgSize==(0,0):

self.imgSize=(self.letterWidth+2,self.letterHeight+2)

self.imgWidth,self.imgHeight=self.imgSize

self.img=Image.new(self.imgMode, self.imgSize, self.bg_color)

self.drawBrush=ImageDraw.Draw(self.img)

textY0= (self.imgHeight-self.letterHeight+1)/2textY0=int(textY0)

textX0= int((self.imgWidth-self.letterWidth+1)/2)PRint'text location:',(textX0,textY0)print'text size (width,height):',self.letterWidth,self.letterHeightprint'img size(width,height):',self.imgSize#if textX0<0 or textY0<0:#raise Exception('size error text location x0:%d,y0:%d'%(textX0,textY0))self.drawBrush.text((textX0,textY0), self.letters, fill=self.fg_color,font=self.font)defSaveImg(self,saveName=''):if''==saveName.strip():

saveName= str(self.letters.encode('gb2312'))+'.png'fileName,file_format= saveName.split('.')

fileName+='_'+str(self.fontsize)+'.'+file_formatprintfileName,file_format

self.img.save(fileName, file_format)defShow(self):

self.img.show()defclearpictures():importos

png=os.listdir(os.curdir)foriinpng:ifos.path.splitext(i)[1]==".png":

os.remove(i)if__name__=='__main__':

letterList=[]letterList.append(LetterImage(bg_color=(0,0,255),fontsize=10))

letterList.append(LetterImage(fontFile='',bg_color=(0,0,255),fontsize=400))

letter=[u'u',u'v']

num_letter= 2svd_u=[]

svd_s=[]

svd_v=[]importcv2

mergeImg= np.zeros((470,444))

npareiImg=[]foriinrange(num_letter):

letterList[i].GenLetterImage(letter[i])#letterList[i].Show()#letterList[i].SaveImg()grayImg =ImageOps.grayscale(letterList[i].img)

grayImg= grayImg.resize((222,470),resample=Image.BICUBIC)

npareiImg.append( np.asarray(grayImg))

cv2.namedWindow('%s'%i)

cv2.imshow('%s'%i, npareiImg[i])

mergeImg[0:470,i*222:(i+1)*222]=npareiImg[i]

u,s,v=np.linalg.svd(npareiImg[i])print'u and img \'s shape',u.shape,npareiImg[i].shape

svd_u.append(u)

svd_v.append(v)

svd_s.append(s)#mergeImgNp=Image.fromarray(mergeImg)#, mode)#mergeImgNp.show()uDifNorm=np.linalg.norm(svd_u[0]-svd_u[1])printuDifNorm

vDifNorm= np.linalg.norm(svd_v[0]-svd_v[1])printvDifNorm

sDifNorm= np.linalg.norm(svd_s[0]-svd_s[1])printsDifNorm

ou_norm= np.linalg.norm(np.asarray(npareiImg[0])-np.asarray(npareiImg[1]))printou_norm

f=open('record.txt','a')

lines=[]

lines.append('letters: %s,%s'%(letter[0],letter[1]))

lines.append('SVD u diff norm:\t%f'%uDifNorm)

lines.append('SVD v diff norm:\t%f'%vDifNorm)

lines.append('SVD s diff norm:\t%f'%sDifNorm)

lines.append('Ou norm: \t%f'%ou_norm)

str_to_write='\n'.join(lines)+'\n'printstr_to_write

f.write(str_to_write)

f.close()

cv2.waitKey()

上面的测试后部分是对图像做SVD变换的一点实验。

显示的结果(图像已经被resize到统一大小,代码中的字符图像类生成的图像其实会根据字体大小自动设定)

当然,生成这种测试图像也不一定就非得用PIL或者python,matlab中应该也可以,其实也就是先生成一个空的图像矩阵,然后调用写字符的函数在这个空图像上以特定的字体写上字符串罢了。

使用汉字字体时要注意的问题:一般的做法是在文件开头的位置加上#-*- coding:gb2312 -*-指定使用中文编码。这样一般不会有错。但有时可能我们需要对部分字符串转换编码,这时我们可利用字符对象的encode、decode方法。encode是对当前字符使用指定的编码方案重新编码。decode是使用指定的编码方案进行解码。两者都是码制的转换,但使用时往往容易弄错。encode其实是对本身为unicode的字符使用指定的编码方案进行编码,而decode则是使用指定编码将字符解码为unicode编码。所以在使用encode时,如果本身不是unicode码就会出错,在使用decode时,如果不知道本身所使用的编码方案也会出错.

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航