python3使用draw.text画图,解决python3中的truetype乱码

本文介绍在Python3中使用draw.text进行图片标注时遇到的truetype字体乱码问题及其解决方案。通过调整字体文件路径为Hiragino Sans GB.ttc,并确保text编码与truetype方法中的encoding一致,成功解决中文乱码问题。

背景:我们在做UI自动化截图的时候,为了方便,截图中记录一些文本内容

一、处理用到的类:

Image+ImageDraw+ImageFont

二、对应的方法:

1、打开图片Image.open()

2、找到画笔ImageDraw.Draw(image)

3、加载并创建字体对象ImageFont.truetype(),乱码就在这一步。路径和对应的编码格式

4、文本画入到图片draw.text

5、保存图片对象image.save()

image_path="picture/web.png"    
image = Image.open(image_path)
draw = ImageDraw.Draw(image)
font_path = os.path.join("assets", "FiraMono-Regular.ttf")
font = ImageFont.truetype(font_path, 30)
# 显示图片
draw.text((400, 1100), text, font=font, fill=color, stroke_width=5, stroke_fill=(249, 205, 173))
# 保存
image.save(image_path)

三、遇到的问题,打印出来的中文乱码:

一开始以为是text(文本内容)编码导致的,然后用encode编码,decode解码都不行。最后发现是解析的文件不太对

四、解决python3中的truetype乱码:

1、乱码主要是在加载创建字体对象的时候truetype对象影响到的

2、解决:在其中的font路径改为Hiragino Sans GB.ttc的形式

image_path="picture/web.png"
# 打开图片
image = Image.open(image_path)
# 找到画笔,将图片对象放入
draw = ImageDraw.Draw(image)
# 用Hiragino Sans GB.ttc的形式
font_path = os.path.join("assets", "Hiragino Sans GB.ttc")
# 加载并创建一个字体对象,给定字体的大小、编码
font = ImageFont.truetype(font_path, size=30, encoding="gbk")
# 显示图片,坐标(100, 100)处开始,画出color颜色文本.stroke_width=5是模糊度,stroke_fill是背景颜色
draw.text((400, 1100), text, font=font, fill=color, stroke_width=5, stroke_fill=(249, 205, 173))
# 保存
image.save(image_path)

3、如果还是编码有问题需要改truetype方法中的encoding,这个是写入图片文本编码格式,与text方法中的text编码形式一样。

----如果不一样,encoding="unic",text进行编码尝试

附录:truetype源码

代码提交记录

from PIL import Image,ImageDraw,ImageFont,ExifTags #步骤1.打开图像并处理exif旋转 img = Image.open("c:/tmp/pic/grass.jpg") def correctOrientation(img): #correct:纠正 orientation:方向 #根据 exif数据判断,img里的图像如有颠倒或旋转则生成一副将其摆正的图返回 if hasattr(img,"_getexif"): #判断img有没有_getexif函数 exif = img._getexif() #获取图像 exif 信息,返回值是个字典 if exif != None: orientation = exif[getExifKeyCode("Orientation")] if orientation == 3: #手机顶部往右拍 img = img.rotate(180,expand=True) elif orientation == 6: #手机正常竖着拍(顶部朝上) img = img.rotate(270,expand=True) #270度旋转(等价于-90) elif orientation == 8: #手机顶部朝下拍 img = img.rotate(90,expand=True) else: pass #无exif数据时保持原图 return img #无exif属性时保持原图 correctOrientation(img) def getExifKeyCode(keyStr): #根据属性名称字符串求属性代号 for x in ExifTags.TAGS.items(): if x[1] == keyStr: return x[0] return None #步骤2,在右下角写入文字 def writeTextToImage(img,text,myFont): #在img中以字体myFont在右下角写入字符串text #会改变img中的图像 bbox = ImageFont.getbbox(img) #返回(x0, y0, x1, y1) w = bbox[2] - bbox[0] #宽度=x1-x0ax h = bbox[3] - bbox[1] #高度=y1-y0 #w, h = img.size #fw, fh = myFont.getsize(text) #求text显示出来的高度,宽度 draw = ImageDraw.Draw(img) #创建绘图对象,以后就可以通过draw在img上画图、写字 fw, fh = draw.textsize(text,font=myFont) x, y = w - fw -30, h - fh - 30 #计算text的左上角的位置 draw.rectangle((x-5,y-5,x+fw+5,y+fh+5),outline='white') draw.text((x,y),text,(255,255,255),font=myFont) text = "sample Text" # 自定义文字内容 myFont = ImageFont.truetype("arial.ttf", 24) # 指定字体和大小(需安装字体文件,如Arial) writeTextToImage(img,text,myFont) 详细分析每一段代码,请问我这个代码有没有错误或者需要改进的地方
最新发布
09-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值