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

基于x、y、width、height拼接图像切片出现错位,问题出在哪?

图像切片拼接报纸页面错位问题解决

我尝试从多个图像切片重建报纸整版页面,每个切片文件名包含坐标编码,格式为01_<x>_<y>_<width>_<height>.jpg(示例:01_181.5_41_738_148.jpg)。页面HTML中切片的CSS定位规则如下:

<a href="slice.jpg" style="top:41px; left:181.5px; width:738px; height:148px"></a>

原本预期通过这些坐标拼接出完整页面,但实际输出出现部分区域重叠、内容缺失的问题,布局与原页面不符。以下是我使用的Python代码:

import requests
from PIL import Image
from io import BytesIO

urls = [
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_38_43_141.5_359.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_181.5_41_738_148.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_38.5_406_137_180.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_36.5_579_147_359.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_182.5_184_739_283.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_182.5_466_592_474.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_774.5_465_143_263.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_773.5_725_144_215.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_39.5_938_440_310.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_38.5_1242_440_147.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_477.5_937_151_458.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_625.5_937_294_451.jpg"
]

tiles = []
max_w, max_h = 0, 0

for url in urls:
    name = url.split("/")[-1].replace(".jpg", "")
    _, x, y, w, h = name.split("_")

    x, y, w, h = map(float, [x, y, w, h])

    img = Image.open(BytesIO(requests.get(url).content))

    tiles.append((img, round(x), round(y)))

    max_w = max(max_w, round(x + w))
    max_h = max(max_h, round(y + h))

canvas = Image.new("RGB", (max_w, max_h), (255, 255, 255))

for img, x, y in tiles:
    canvas.paste(img, (x, y))

canvas.save("output.jpg")

问题原因

代码中直接对x/y坐标做四舍五入处理,而网页CSS使用的是精确浮点坐标,四舍五入会导致像素级偏移,累积后出现重叠或间隙。同时,按标注值四舍五入计算画布尺寸,也会因精度丢失导致边缘内容截断。

修正后的代码

保留精确浮点坐标计算画布尺寸,粘贴时采用向下取整匹配CSS定位逻辑,避免亚像素偏移:

import requests
from PIL import Image
from io import BytesIO
import math

urls = [
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_38_43_141.5_359.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_181.5_41_738_148.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_38.5_406_137_180.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_36.5_579_147_359.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_182.5_184_739_283.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_182.5_466_592_474.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_774.5_465_143_263.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_773.5_725_144_215.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_39.5_938_440_310.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_38.5_1242_440_147.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_477.5_937_151_458.jpg",
"https://epaper.janayugomonline.com/assets/epaper/thiruvananthapuram/2026/04/05/slices/01_625.5_937_294_451.jpg"
]

tiles = []
max_w, max_h = 0.0, 0.0

for url in urls:
    name = url.split("/")[-1].replace(".jpg", "")
    _, x, y, w, h = name.split("_")

    x, y, w, h = map(float, [x, y, w, h])

    img = Image.open(BytesIO(requests.get(url).content))
    tiles.append((img, x, y))

    # 用浮点运算计算画布最大尺寸
    current_max_w = x + w
    current_max_h = y + h
    max_w = max(max_w, current_max_w)
    max_h = max(max_h, current_max_h)

# 画布尺寸向上取整,避免边缘内容截断
canvas_width = math.ceil(max_w)
canvas_height = math.ceil(max_h)
canvas = Image.new("RGB", (canvas_width, canvas_height), (255, 255, 255))

for img, x, y in tiles:
    # 向下取整坐标,匹配CSS左上角定位逻辑
    paste_x = math.floor(x)
    paste_y = math.floor(y)
    canvas.paste(img, (paste_x, paste_y))

canvas.save("output.jpg")

额外优化建议

  • 验证切片实际尺寸与文件名标注的width/height是否一致,若有差异,以图像实际尺寸为准计算画布大小,进一步减少误差。
  • 添加异常处理逻辑,防止请求图像失败导致程序中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:05:01