搞了好几个晚上,终于!
1、问题产生↓
一开始是想要使用stylecloud库生成爬虫后所得文本的词云图,Spyder报错AttributeError: 'ImageDraw' object has no attribute 'textsize'
追踪到报错的代码位于anaconda\Lib\site-packages\icon_font_to_png\icon_font.py:
width, height = draw.textsize(self.css_icons[icon], font=font)
2、产生问题的原因↓
虽然报错函数的库的名字是icon_font_to_png,但是阅读代码后发现是因为pillow库的Imagedraw
经以下文章得知,pillow在10.0.0版本后,textsize()函数被移除,官方建议使用textbbox()或者textlength()代替【已解决 | 附代码】AttributeError: ‘ImageDraw‘ object has no attribute ‘textsize‘_imagedraw' object has no attribute 'textsize-CSDN博客
3、解决问题的过程及方法↓
①降版本法
大多数人使用将pillow降版本至textsize()函数没被更换前的9.5.0版本的方法解决:
pip install pillow==9.5.0
但降版本后随之而来产生了Windows fatal exception: access violation的报错,Spyder内核重启了
此时以为是因为PIL库文件夹设置为这种状态引起的访问权限不够被windows系统拒绝的问题
(因为曾经改成功过一次,并成功出了图一次,后续发现状态恢复成原来的状态,一改完就回到这种状态,且持续报同样的错)
经过一番折腾,发现文件夹该状态是无法更改的,无论是点击变成□,还是在该页面的安全——高级里添加用户且设置权限为“完全控制”,而且该状态并不代表是完全的“只读”状态,完全的“只读状态”是“√”
于是又回到pillow库本身的问题,研究pillow官网发现是9.5.0版本的pillow不适用于3.12版本的Python:
Python Support - Pillow (PIL Fork) 11.2.0.dev0 documentation
于是卸载pillow库,又重新下回原来的11.1.0版本
②更换函数改写代码法
因为降版本导致了版本不兼容问题,于是研究原本的内置官方代码,并根据pillow官网的建议,通过阅读多方文章,选择了将textsize()换成textbbox()
分析对比更换前后的函数,确定更换的代码思路↓
pillow==10.1.0版本前:ImageDraw.textsize()函数返回用指定字体对象显示给定字符串所需要的图像尺寸,即宽width和高height两个数据
待更改的代码:
width, height = draw.textsize(self.css_icons[icon], font=font)
pillow==10.1.0版本开始:ImageDraw.textbbox()函数返回相对于给定锚点的给定文本的边界框(以像素为单位) ,当以提供的方向、特征和语言的字体呈现时的上下左右边框,即(left, top, right, bottom)
边界框四个数据。详见官网:ImageDraw 模块 - Pillow (PIL Fork) 11.2.0.dev0 文档
ImageDraw.textbbox(xy, text, font=None, anchor=None, spacing=4, align='left', direction=None, features=None, language=None, stroke_width=0, embedded_color=False, font_size=None)
- xy – 文本的锚点坐标。
- text – 要测量的文本。如果包含换行符,则文本将传递给multiline_textbbox()。
- font – FreeTypeFont实例。
对比发现,ImageDraw.textbbox()函数比ImageDraw.textsize()函数需要传入xy这个二维锚点坐标参数,而且返回的数据不再是直接的文本的宽和高,共计2个数据,而是文本的上下左右的位置,共计4个数据
因此使xy为(0,0),通过所得的left,top,right,bottom构造出width和height,即
width = right - left
height = top - bottom
因此所得更改后代码如下:
left, top, right, bottom = draw.textbbox((0, 0), self.css_icons[icon], font=font)
width, height = right - left, top - bottom
代码修改自AttributeError: ‘ImageDraw‘ object has no attribute ‘textsize‘ 解决方案 - 知乎
或者
text_bounds=draw.textbbox((0,0),self.css_icons[icon], font=font)
width = text_bounds[2] - text_bounds[0]
height = text_bounds[3] - text_bounds[1]
顺畅运行做出了图!
4、问题解决感想↓
这么一看似乎又是绕远路了,明明问题很简单,一开始坚持改代码就好了,但铁球跑里的杰洛说过:“绕远路就是走捷径”,绕远路的过程又学会了很多东西,最后也成功解决问题了!
也许代码高手就是走这么一个个远路,奋斗一个个深夜才有所成就的吧,嘿嘿~