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

随机布局真实风格文档图像集的布局生成算法及Python3实现咨询

随机单栏文档布局生成实现方案

核心实现逻辑

  • 采用递归二分空间切分法生成布局,严格规避整页左右双栏结构:从扣除全局页边距的20001500有效内容区出发,每次随机选择切分方向,切分后保证两个子块都满足最小宽300、最小高500*的尺寸要求,直到块体无法再做合规切分,即标记为最终布局单元。
  • 切分方向做概率倾斜:80%概率选择上下方向切分(保证整体阅读流是从上到下的单栏逻辑),20%概率在块体内部做小范围左右切分(比如段落旁搭配窄幅配图),从规则层面杜绝生成从页顶贯通到页底的双栏布局。
  • 每个最终布局单元随机匹配真实PDF常见的元素类型:正文段落、内嵌配图、代码块,通过细节渲染(如正文行长随机浮动、配图带边框、代码块带浅灰底)模拟真实纸质文档的观感,避免人工生成的违和感。

可运行Python3实现代码

import random
from PIL import Image, ImageDraw

# 严格匹配需求的固定参数
CANVAS_SIZE = (2000, 1500)  # 目标纸张尺寸 宽*高
MIN_BLOCK_SIZE = (300, 500) # 布局单元最小尺寸要求
PAGE_MARGIN = 100            # 模拟真实文档的全局页边距留白

def split_block(block):
    """递归切分布局块,严格校验最小尺寸,避免不合规的细碎块"""
    x, y, w, h = block
    min_w, min_h = MIN_BLOCK_SIZE
    # 判断可切分方向:切分后的子块不能小于最小尺寸
    can_split_vertical = (h - min_h) >= min_h  # 上下切分可行性
    can_split_horizontal = (w - min_w) >= min_w # 块内左右切分可行性
    if not can_split_vertical and not can_split_horizontal:
        return [block]
    
    # 切分方向选择:优先上下切分(80%权重),避免整页双栏
    choice_pool = []
    if can_split_vertical:
        choice_pool.extend(["vertical"] * 4)
    if can_split_horizontal:
        choice_pool.append("horizontal")
    split_dir = random.choice(choice_pool)

    if split_dir == "vertical":
        # 上下随机切分
        split_pos = random.randint(y + min_h, y + h - min_h)
        upper_block = (x, y, w, split_pos - y)
        lower_block = (x, split_pos, w, (y + h) - split_pos)
        return split_block(upper_block) + split_block(lower_block)
    else:
        # 块内左右随机切分
        split_pos = random.randint(x + min_w, x + w - min_w)
        left_block = (x, y, split_pos - x, h)
        right_block = (split_pos, y, (x + w) - split_pos, h)
        return split_block(left_block) + split_block(right_block)

def render_single_block(draw, block):
    """渲染单个布局单元,模拟真实文档视觉效果"""
    x, y, w, h = block
    block_type = random.choice(["paragraph", "embedded_image", "code_snippet"])
    
    if block_type == "paragraph":
        # 模拟正文:等距排列的随机长度浅灰横线
        line_interval = 32
        for line_top in range(y + 30, y + h - 30, line_interval):
            line_width = random.randint(int(w*0.7), int(w*0.95))
            draw.line([(x+30, line_top), (x+30 + line_width, line_top)], fill=(80,80,80), width=4)
    elif block_type == "embedded_image":
        # 模拟内嵌配图:柔和色块加细边框
        img_color = (random.randint(180,220), random.randint(180,220), random.randint(180,220))
        draw.rectangle(
            [(x+20, y+20), (x + w - 20, y + h - 20)],
            fill=img_color, outline=(0,0,0), width=2
        )
    elif block_type == "code_snippet":
        # 模拟代码块:浅灰背景加彩色等距行
        draw.rectangle(
            [(x+20, y+20), (x + w - 20, y + h - 20)],
            fill=(240,240,240), outline=(0,0,0), width=2
        )
        line_interval = 30
        color_pool = [(0,100,200), (0,120,0), (180,50,50)]
        for line_top in range(y + 40, y + h - 40, line_interval):
            line_width = random.randint(int(w*0.3), int(w*0.8))
            line_color = random.choice(color_pool)
            draw.line([(x+40, line_top), (x+40 + line_width, line_top)], fill=line_color, width=3)

if __name__ == "__main__":
    # 初始化白色纸张画布
    doc_img = Image.new("RGB", CANVAS_SIZE, (255,255,255))
    draw_handle = ImageDraw.Draw(doc_img)
    # 扣除全局页边距得到有效内容根块
    margin = PAGE_MARGIN
    root_layout_block = (
        margin, margin,
        CANVAS_SIZE[0] - 2*margin,
        CANVAS_SIZE[1] - 2*margin
    )
    # 生成全页随机布局
    final_blocks = split_block(root_layout_block)
    # 逐块渲染内容
    for block in final_blocks:
        render_single_block(draw_handle, block)
    # 导出生成的文档图像
    doc_img.save("random_generated_doc.png")

使用说明

  • 运行前安装依赖:执行pip install pillow即可,无其他复杂环境要求
  • 生成的图像严格匹配所有参数要求:纸张尺寸固定为20001500,所有布局单元宽高都不低于300500,无贯通式双栏结构
  • 可根据实际需求调整随机概率(比如上下切分的权重、元素类型的占比),进一步贴近目标文档的观感

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 04:06:02