You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对Rect对象列表排序?基于PymuPDF的PDF阅读器开发问题

解决PymuPDF Rect对象排序问题

问题根源

PymuPDF的Rect对象没有默认实现比较运算符(比如__lt__),直接调用sort()会抛出"无法进行小于比较"的错误。另外你的排序规则是依赖前一个元素的贪心排序,并非全局排序逻辑,无法用普通的sorted()方法直接处理。

解决方案

分两步实现你的排序规则:

  1. 先选出最靠上且最靠左的Rect作为起始元素;
  2. 从剩余元素中反复选出与当前最后一个Rect距离最近的元素,直到所有元素处理完毕。

代码实现

import fitz  # 导入PymuPDF
import math

def calculate_rect_distance(rect_a, rect_b):
    # 计算两个Rect中心的欧氏距离,可根据需求替换为其他距离算法
    center_a_x = (rect_a.x0 + rect_a.x1) / 2
    center_a_y = (rect_a.y0 + rect_a.y1) / 2
    center_b_x = (rect_b.x0 + rect_b.x1) / 2
    center_b_y = (rect_b.y0 + rect_b.y1) / 2
    return math.hypot(center_a_x - center_b_x, center_a_y - center_b_y)

def custom_sort_rects(rect_list):
    if not rect_list:
        return []
    
    # 初始化排序结果,先加入最靠上靠左的Rect
    sorted_result = []
    # PymuPDF坐标系中y轴向下递增,y0越小越靠上;x0越小越靠左
    first_rect = min(rect_list, key=lambda r: (r.y0, r.x0))
    sorted_result.append(first_rect)
    remaining_rects = [r for r in rect_list if r != first_rect]
    
    # 贪心式添加距离最近的Rect
    while remaining_rects:
        last_in_result = sorted_result[-1]
        next_rect = min(remaining_rects, key=lambda r: calculate_rect_distance(last_in_result, r))
        sorted_result.append(next_rect)
        remaining_rects.remove(next_rect)
    
    return sorted_result

可选调整

如果不需要中心距离,可替换calculate_rect_distance为其他逻辑:

  • 左上角坐标距离:
def calculate_rect_distance(rect_a, rect_b):
    return math.hypot(rect_a.x0 - rect_b.x0, rect_a.y0 - rect_b.y0)
  • 曼哈顿距离(计算更快,适合对性能敏感的场景):
def calculate_rect_distance(rect_a, rect_b):
    center_a_x = (rect_a.x0 + rect_a.x1) / 2
    center_a_y = (rect_a.y0 + rect_a.y1) / 2
    center_b_x = (rect_b.x0 + rect_b.x1) / 2
    center_b_y = (rect_b.y0 + rect_b.y1) / 2
    return abs(center_a_x - center_b_x) + abs(center_a_y - center_b_y)

内容的提问来源于stack exchange,提问作者Dat_guy_who_hangs_out

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:10:39