当前位置: 首页 > article >正文

避坑指南:Pillow中getbbox替换getsize时,别再踩‘ValueError: too many values to unpack‘这个坑了

深度解析Pillow中getbbox替换getsize的正确姿势从报错到精准计算当你在YOLOv5或其他计算机视觉项目中遇到FreeTypeFont object has no attribute getsize的报错时说明你正在使用的Pillow库版本已经移除了这个过时的方法。很多开发者会按照文档建议改用getbbox()但却意外踩入了另一个坑——ValueError: too many values to unpack。这看似简单的API替换背后实际上隐藏着图像处理中关于文本定位的重要概念差异。1. 为什么getsize会被弃用理解Pillow的API演进Pillow作为Python图像处理的标准库之一其API设计一直在不断优化。getsize()方法之所以被标记为弃用并最终移除主要是因为它的设计过于简单无法满足现代图像处理中对文本布局更精确控制的需求。getsize()返回的是一个简单的二元组(width, height)这在大多数基础场景下看似够用但实际上存在几个关键缺陷无法处理文本的基线(baseline)信息不能准确反映非零起点文本的实际占用空间缺乏对复杂字体布局的支持# 旧版用法已弃用 width, height font.getsize(Hello World) # 新版替代方案 bbox font.getbbox(Hello World) # 返回(x0, y0, x1, y1)Pillow维护团队选择用getbbox()替代getsize()正是为了提供更丰富的文本度量信息。这个改变虽然增加了些许复杂性但却为开发者带来了更强大的控制能力。2. getbbox的返回值解析不只是宽高那么简单getbbox()方法返回的是一个包含四个整数的元组分别代表文本边界框的坐标x0文本边界框左上角的x坐标y0文本边界框左上角的y坐标x1文本边界框右下角的x坐标y1文本边界框右下角的y坐标这四个值共同定义了一个矩形区域准确描述了文本在图像中所占据的空间范围。理解这些坐标的含义对于正确处理文本布局至关重要。坐标值描述与宽高的关系x0文本左边界通常为0但非绝对y0文本上边界可能为负值考虑字母下行部分x1文本右边界实际宽度 x1 - x0y1文本下边界实际高度 y1 - y0常见误区很多开发者会直接尝试w, h font.getbbox(text)[2:]只取后两个值作为宽高。这种做法在文本左上角坐标为(0,0)时看似可行但实际上忽略了y0可能为负的情况如字母g、y等有下行部分的字符无法正确处理非零起点文本导致后续文本定位计算出现偏差3. 从报错到正确解包解决ValueError的三种方案当开发者直接从getsize切换到getbbox时最常见的错误就是尝试将四个值解包到两个变量中# 错误写法直接替换导致ValueError w, h font.getbbox(text) # 尝试解包4个值到2个变量3.1 完整解包法推荐最严谨的做法是完整解包四个坐标值然后计算实际宽高x0, y0, x1, y1 font.getbbox(text) width x1 - x0 height y1 - y0这种方法明确区分了坐标和尺寸概念适用于任何文本位置情况代码意图清晰易于维护3.2 切片取值法有条件使用如果确定文本总是从(0,0)开始可以只取后两个坐标width, height font.getbbox(text)[2:] # 只取x1和y1适用条件文本左上角确实在(0,0)位置不需要考虑文本基线偏移快速修复代码的临时方案3.3 直接计算法一行代码结合元组解包和计算可以用一行代码完成width, height (lambda b: (b[2]-b[0], b[3]-b[1]))(font.getbbox(text))这种方法虽然简洁但可读性稍差适合熟悉Python的高级开发者。4. 实战应用在YOLOv5中正确替换getsize让我们看一个YOLOv5中的实际修改案例。在标注工具类Annotator中原始代码可能如下def box_label(self, box, label, color(128, 128, 128), txt_color(255, 255, 255)): if self.pil or not is_ascii(label): self.draw.rectangle(box, widthself.lw, outlinecolor) if label: w, h self.font.getsize(label) # 旧方法 outside box[1] - h 0 self.draw.rectangle( (box[0], box[1] - h if outside else box[1], box[0] w 1, box[1] 1 if outside else box[1] h 1), fillcolor, ) self.draw.text((box[0], box[1] - h if outside else box[1]), label, filltxt_color, fontself.font)修改后的正确版本应该是def box_label(self, box, label, color(128, 128, 128), txt_color(255, 255, 255)): if self.pil or not is_ascii(label): self.draw.rectangle(box, widthself.lw, outlinecolor) if label: # 新版正确写法 x0, y0, x1, y1 self.font.getbbox(label) w, h x1 - x0, y1 - y0 # 考虑文本基线偏移 text_y_offset y0 # 通常为负值用于调整文本垂直位置 outside box[1] - h text_y_offset 0 self.draw.rectangle( (box[0], box[1] - h text_y_offset if outside else box[1], box[0] w 1, box[1] 1 if outside else box[1] h 1 text_y_offset), fillcolor, ) self.draw.text((box[0], box[1] - h text_y_offset if outside else box[1]), label, filltxt_color, fontself.font)关键改进点使用完整解包获取文本边界框坐标通过减法计算实际宽高考虑y0偏移量文本基线问题调整文本框和文本的垂直位置计算5. 高级话题文本度量的更多细节理解getbbox()的返回值只是文本处理的第一步。要真正掌握精准的文本布局还需要了解以下几个关键概念5.1 文本基线(Baseline)问题在字体排版中基线是字母排列的参考线。大部分字母坐在基线上但有些字母如g,y,j等会有下行部分(descender)。getbbox()的y0通常会反映这一点可能是负值。# 不同字符的边界框对比 print(font.getbbox(Hello)) # 可能返回 (0, -3, 100, 20) print(font.getbbox(yg)) # 可能返回 (0, -15, 80, 20)5.2 字体度量(Font Metrics)详解Pillow提供了更多字体度量方法可以与getbbox()配合使用方法描述返回类型getmask(text)生成文本的位图掩码Image对象getlength(text)文本的总长度floatgetbbox(text)文本的边界框(x0,y0,x1,y1)5.3 多行文本处理当处理多行文本时需要逐行计算并累加高度lines text.split(\n) total_height 0 max_width 0 for line in lines: x0, y0, x1, y1 font.getbbox(line) line_width x1 - x0 line_height y1 - y0 total_height line_height if line_width max_width: max_width line_width5.4 性能优化技巧频繁调用getbbox()可能影响性能特别是在处理大量文本时。可以考虑缓存常用文本的尺寸预计算字体最大高度对固定文本提前计算并存储结果# 字体高度缓存示例 _font_height_cache {} def get_font_height(font, sample_textHg): if font not in _font_height_cache: x0, y0, x1, y1 font.getbbox(sample_text) _font_height_cache[font] y1 - y0 return _font_height_cache[font]6. 常见问题排查与调试技巧即使正确使用了getbbox()在实际项目中仍可能遇到各种文本布局问题。以下是几个常见场景及解决方法6.1 文本位置偏移问题现象替换getsize()后文本位置不正确特别是垂直方向有偏移。原因没有考虑y0通常是负值对文本位置的影响。解决方案x0, y0, x1, y1 font.getbbox(text) width x1 - x0 height y1 - y0 # 绘制文本时考虑y0偏移 draw.text((x_pos, y_pos - y0), text, fontfont)6.2 文本截断问题现象文本框无法完整显示文本内容特别是下行字母被截断。原因仅使用高度(height)而忽略了y0偏移。解决方案# 计算文本框高度时应考虑y0 text_box_height height - y0 # 而不是直接使用height6.3 性能下降问题现象替换为getbbox()后程序运行速度明显变慢。原因getbbox()可能比getsize()计算更复杂频繁调用影响性能。优化方案# 批量处理文本尺寸计算 texts [label1, label2, label3] bboxes [font.getbbox(text) for text in texts] sizes [(b[2]-b[0], b[3]-b[1]) for b in bboxes]6.4 多字体混合问题现象使用不同字体时文本对齐不一致。原因不同字体的基线(baseline)和度量(metrics)可能不同。解决方案def get_text_vertical_position(font, text, y_pos): _, y0, _, y1 font.getbbox(text) return y_pos - y0 # 统一基于基线定位7. 最佳实践总结在Pillow中正确使用getbbox()替换getsize()不仅是一个简单的API变更更是提升文本处理精确度的重要机会。以下是关键要点始终完整解包四个坐标值避免直接切片取值实际宽高应通过减法计算x1-x0, y1-y0考虑文本基线偏移特别是y0值的影响对性能敏感场景实施缓存策略多行文本需要逐行计算并累加尺寸不同字体可能需要特殊处理特别是混合使用时# 最终推荐的标准写法 def get_text_size(font, text): 安全获取文本尺寸的标准函数 x0, y0, x1, y1 font.getbbox(text) return (x1 - x0, y1 - y0, y0) # 返回宽高和基线偏移在实际项目中建议创建一个文本处理工具类封装这些细节避免在业务代码中重复处理坐标计算。这不仅能提高代码可维护性还能确保文本布局的一致性。

相关文章:

避坑指南:Pillow中getbbox替换getsize时,别再踩‘ValueError: too many values to unpack‘这个坑了

深度解析Pillow中getbbox替换getsize的正确姿势:从报错到精准计算 当你在YOLOv5或其他计算机视觉项目中遇到FreeTypeFont object has no attribute getsize的报错时,说明你正在使用的Pillow库版本已经移除了这个过时的方法。很多开发者会按照文档建议改用…...

3分钟掌握PUBG罗技鼠标宏:新手也能轻松压枪的完整指南

3分钟掌握PUBG罗技鼠标宏:新手也能轻松压枪的完整指南 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 还在为《绝地求生》中难以控制…...

Office RibbonX Editor:5分钟学会定制你的Office功能区界面

Office RibbonX Editor:5分钟学会定制你的Office功能区界面 【免费下载链接】office-ribbonx-editor An overhauled fork of the original Custom UI Editor for Microsoft Office, built with WPF 项目地址: https://gitcode.com/gh_mirrors/of/office-ribbonx-e…...

注释覆盖率从42%→91%仅用8小时,DeepSeek R1/R2模型注释优化全链路实操,

更多请点击: https://kaifayun.com 第一章:注释覆盖率跃升的工程价值与DeepSeek模型适配性洞察 注释覆盖率并非代码“装饰”,而是可量化的知识沉淀密度指标。当函数级注释覆盖率从32%提升至89%,CI流水线中PR评审平均耗时下降41%&…...

告别AssetBundle手动管理:Unity Addressables保姆级配置与本地服务器搭建实战

Unity Addressables全流程实战:从资源管理到热更新闭环如果你曾经被AssetBundle的依赖关系折磨得焦头烂额,或者为资源热更新方案纠结不已,那么Addressables可能就是你在寻找的解决方案。这套由Unity官方推出的资源管理系统,不仅保…...

别再死记硬背了!用‘重复局面’这道CSP真题,带你彻底搞懂C++中map容器的使用场景与底层逻辑

从国际象棋到红黑树:用CSP真题解锁C map的底层力量 国际象棋大师卡斯帕罗夫曾说:"棋局如同程序,每一步都是对数据结构的选择。"当我们面对CSP考试中那道看似简单的"重复局面"题时,表面上是考察字符串处理能力…...

Arduino打地鼠游戏机:从74HC595矩阵驱动到状态机编程全解析

1. 项目概述:用Arduino复刻经典打地鼠游戏作为一个电子爱好者,我总想把手头的Arduino和各种元器件玩出点新花样。这次,我决定挑战一个经典街机项目——电子打地鼠。市面上虽然有现成的玩具,但自己从头设计、画板、编程&#xff0c…...

告别Houdini!用UE5.2原生PCG框架,像搭积木一样复用你的关卡设计

告别Houdini!用UE5.2原生PCG框架,像搭积木一样复用你的关卡设计在游戏开发的世界里,程序化内容生成(PCG)一直是提高效率的圣杯。但长期以来,开发者们不得不在Houdini等第三方工具中忍受工作流割裂的痛苦——节点操作不直观、资源解…...

从原理到防御:手把手教你用Python模拟ZipCrypto加密,理解密码为何能被‘撞开’

从零构建ZipCrypto加密模拟器:Python实战与密码安全深度解析 当你用鼠标双击那个带锁的ZIP图标,输入密码后看到文件顺利解压时,是否好奇过背后的魔法?现代加密算法就像数字世界的机械钟表——精密的齿轮咬合运转,而我们…...

猫抓浏览器扩展技术深度解析:构建高效流媒体资源捕获工作流

猫抓浏览器扩展技术深度解析:构建高效流媒体资源捕获工作流 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓浏览器扩展是一个基于C…...

保姆级教程:用Prometheus Operator在K8S里一键搞定监控全家桶(附Grafana仪表盘)

云原生监控革命:用Prometheus Operator构建K8S智能监控体系 当Kubernetes集群规模突破50个节点时,传统监控方案的维护成本会呈指数级增长。我曾亲眼见证一个电商团队在"黑五"大促期间,因为手动配置的Prometheus抓取规则失效&#x…...

终极免费解决方案:如何用Neat Bookmarks拯救你混乱的Chrome书签

终极免费解决方案:如何用Neat Bookmarks拯救你混乱的Chrome书签 【免费下载链接】neat-bookmarks A neat bookmarks tree popup extension for Chrome [DISCONTINUED] 项目地址: https://gitcode.com/gh_mirrors/ne/neat-bookmarks 还在为满屏混乱的Chrome书…...

HoRain云--Ollama 安装

🎬 HoRain 云小助手:个人主页 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。 目录 ⛳️ 推荐 …...

清华大学学位论文LaTeX模板:告别格式烦恼的终极指南

清华大学学位论文LaTeX模板:告别格式烦恼的终极指南 【免费下载链接】thuthesis LaTeX Thesis Template for Tsinghua University 项目地址: https://gitcode.com/gh_mirrors/th/thuthesis 还在为论文格式调整而烦恼吗?清华大学thuthesis LaTeX模…...

别再乱用Bool和Enum了!用UE5的Gameplay Tags重构你的角色状态机(GAS避坑指南)

别再乱用Bool和Enum了!用UE5的Gameplay Tags重构你的角色状态机(GAS避坑指南)当你的ARPG角色同时陷入眩晕、灼烧和减速状态时,传统状态机往往会暴露出致命缺陷——布尔值互相覆盖、枚举组合爆炸、条件判断嵌套成灾。而UE5的Gamepl…...

基于树莓派与ADS1248的高精度多通道RTD温度采集系统设计与实践

1. 项目概述:低成本、高精度的多通道温度采集方案在工业自动化、环境监测或者实验室数据记录领域,多通道、高精度的温度测量一直是个既关键又有点“烧钱”的环节。传统的方案要么通道数有限,要么精度和成本难以兼得,尤其是在需要多…...

MySQL 分区表实战:大表治理的利器与陷阱

开场白 分区表这个东西,我之前一直觉得就是个语法糖,直到有一次运维一张 2 亿行的日志表,查询慢到飞起,索引也建不动了,才认真研究分区表。结果发现分区表确实好用,但坑也不少——分区键选错了、分区裁剪没…...

COM3D2.MaidFiddler:实时内存编辑器与游戏模组开发的技术深度解析

COM3D2.MaidFiddler:实时内存编辑器与游戏模组开发的技术深度解析 【免费下载链接】COM3D2.MaidFiddler Maid Fiddler for COM3D2 -- a real-time value editor for COM3D2 项目地址: https://gitcode.com/gh_mirrors/co/COM3D2.MaidFiddler COM3D2.MaidFidd…...

终极指南:如何在Windows上直接访问Linux RAID阵列数据

终极指南:如何在Windows上直接访问Linux RAID阵列数据 【免费下载链接】winmd WinMD 项目地址: https://gitcode.com/gh_mirrors/wi/winmd 你是否曾面临这样的困境:企业Linux服务器上存储着重要的业务数据,使用mdadm创建的RAID阵列运行…...

污水管网在线监测系统,精准定位污水偷排源头

当前,城市地下排水管网普遍存在“看不见、摸不着”的监管难题。污水偷排、漏检等现场层出不穷,依赖人工进行监测管理的方式无疑是十分困难的。因此,管理部门需要灵活运用先进技术,积极转变观念,实现对污水管网的定量、…...

解放学术资源:caj2pdf——打破CAJ格式壁垒的开源解决方案

解放学术资源:caj2pdf——打破CAJ格式壁垒的开源解决方案 【免费下载链接】caj2pdf Convert CAJ (China Academic Journals) files to PDF. 转换中国知网 CAJ 格式文献为 PDF。佛系转换,成功与否,皆是玄学。 项目地址: https://gitcode.com…...

B站视频缓存转换终极指南:5秒完成m4s到MP4的无损转换

B站视频缓存转换终极指南:5秒完成m4s到MP4的无损转换 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经在B站缓存了珍贵的教…...

别再乱调了!深度解析URP相机Culling Mask与Occlusion Culling,让你的游戏性能提升一个档次

别再乱调了!深度解析URP相机Culling Mask与Occlusion Culling,让你的游戏性能提升一个档次在Unity游戏开发中,性能优化是一个永恒的话题。尤其是使用URP(Universal Render Pipeline)进行开发时,相机的合理配…...

Awoo Installer:如何用这个免费工具快速安装Switch游戏

Awoo Installer:如何用这个免费工具快速安装Switch游戏 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer Awoo Installer是一款专为Ninte…...

从《原神》到独立游戏:聊聊URP相机Stack(Overlay)如何实现那些酷炫的UI与特效

从《原神》到独立游戏:URP相机堆叠技术如何重塑游戏视觉表现当你在《原神》中打开地图界面时,是否注意到背景世界依然保持着动态光影效果?当角色受伤时,那层红色渐隐特效为何能如此自然地覆盖在3D场景之上?这些看似简单…...

基于Arduino与ADXL335的自制地震预警系统:从传感器原理到多点联动实现

1. 项目概述与核心思路最近在捣鼓一个挺有意思的玩意儿——一个能自主工作的地震预警系统。这可不是什么高深莫测的科研项目,而是基于一些常见的电子模块,自己动手就能搭建起来的实用装置。它的核心目标很明确:当检测到建筑物出现异常振动时&…...

Burp插件自动化渗透测试工作流:零基础入门与效率跃迁

1. 这不是“插件合集”,而是渗透测试工作流的底层操作系统重构 你有没有试过在Burp Suite里打开一个新目标,点开Proxy历史,看着几十个HTTP请求发呆——不知道该从哪条请求下手?右键菜单里密密麻麻的“Send to Repeater”“Send to…...

体验低延迟与高稳定性的大模型 API 聚合服务调用感受

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 体验低延迟与高稳定性的大模型 API 聚合服务调用感受 在集成大模型能力到实际应用的过程中,开发者最关心的往往是两个核…...

SharpKeys终极指南:Windows键盘重映射的专业解决方案

SharpKeys终极指南:Windows键盘重映射的专业解决方案 【免费下载链接】sharpkeys SharpKeys is a utility that manages a Registry key that allows Windows to remap one key to any other key. 项目地址: https://gitcode.com/gh_mirrors/sh/sharpkeys 在…...

从UE/Unity转战Godot:一个老引擎开发者的踩坑与真香实录

从UE/Unity转战Godot:一个老引擎开发者的踩坑与真香实录 第一次双击Godot图标时,我正坐在堆满Unity参考书的办公桌前。作为用过五年Unity、三年Unreal的"引擎老油条",我带着审视新玩具的心态点开了这个不到100MB的绿色软件——没想…...