基于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
相关产品推荐
相关产品推荐

