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

如何用Python(Pillow)或JS(Canvas)实现图片分割与右侧边缘镜像包裹

实现图片切片的3D镜像包裹效果

需求:将图片分割为多个切片,每个切片右侧添加镜像包裹的类3D视觉效果,已尝试HTML的context.drawImage()和Python Pillow库,但无法实现镜像部分。

原始Python尝试代码

from PIL import Image

# Open the image
image = Image.open('image.jpeg')

# Divide the image into panels (assuming 3 panels for this example)
width, height = image.size
panel_width = width // 3
panel_height = height
panel1 = image.crop((0, 0, panel_width, panel_height))
panel2 = image.crop((panel_width, 0, panel_width * 2, panel_height))
panel3 = image.crop((panel_width * 2, 0, panel_width * 3, panel_height))

# Add a margin to the right side of each panel
margin = 10

panel1_with_margin = Image.new('RGB', (panel1.width + margin, panel1.height), (255, 255, 255))
panel1_with_margin.paste(panel1, (0, 0))
panel2_with_margin = Image.new('RGB', (panel2.width + margin, panel2.height), (255, 255, 255))
panel2_with_margin.paste(panel2, (0, 0))
panel3_with_margin = Image.new('RGB', (panel3.width + margin, panel3.height), (255, 255, 255))
panel3_with_margin.paste(panel3, (0, 0))

# Combine the panels into a single image
total_width = panel1_with_margin.width + panel2_with_margin.width + panel3_with_margin.width
max_height = max(panel1_with_margin.height, panel2_with_margin.height, panel3_with_margin.height)
combined_image = Image.new('RGB', (total_width, max_height), (255, 255, 255))
combined_image.paste(panel1_with_margin, (0, 0))
combined_image.paste(panel2_with_margin, (panel1_with_margin.width, 0))
combined_image.paste(panel3_with_margin, (panel1_with_margin.width + panel2_with_margin.width, 0))

#Add mirroring and 3d effect here
#...Missed part of the code...

# Save the combined image
combined_image.save('combined_image.jpg')

Python Pillow 解决方案

要实现切片右侧的镜像包裹效果,需要为每个切片生成右侧边缘的水平镜像+渐变透明,模拟3D折叠的侧边:

from PIL import Image, ImageDraw

def add_3d_side(panel, side_width=20):
    # 提取切片右侧边缘区域
    right_edge = panel.crop((panel.width - side_width, 0, panel.width, panel.height))
    # 水平翻转得到镜像
    mirrored_edge = right_edge.transpose(Image.FLIP_LEFT_RIGHT)
    
    # 创建渐变透明层:从完全不透明到完全透明
    gradient = Image.new('L', (side_width, panel.height), 0)
    draw = ImageDraw.Draw(gradient)
    for x in range(side_width):
        # 透明度从255(不透明)降到0(透明)
        alpha = int(255 * (1 - x / side_width))
        draw.line((x, 0, x, panel.height), fill=alpha)
    
    # 将渐变应用到镜像边缘
    mirrored_edge.putalpha(gradient)
    
    # 拼接原切片和镜像侧边
    panel_with_side = Image.new('RGBA', (panel.width + side_width, panel.height))
    panel_with_side.paste(panel, (0, 0))
    panel_with_side.paste(mirrored_edge, (panel.width, 0), mask=mirrored_edge)
    
    return panel_with_side

# 重新处理切片
panel1_3d = add_3d_side(panel1)
panel2_3d = add_3d_side(panel2)
panel3_3d = add_3d_side(panel3)

# 组合所有带3D侧边的切片(不需要额外margin,侧边已经包含间距效果)
total_width = panel1_3d.width + panel2_3d.width + panel3_3d.width
combined_image = Image.new('RGB', (total_width, height), (255, 255, 255))

x_offset = 0
for panel in [panel1_3d, panel2_3d, panel3_3d]:
    combined_image.paste(panel, (x_offset, 0), mask=panel)
    x_offset += panel.width

combined_image.save('3d_sliced_image.jpg')

代码说明

  • add_3d_side函数:提取切片右侧边缘,水平翻转生成镜像,再添加从左到右的透明度渐变,模拟3D侧边的阴影效果
  • 最终拼接时使用RGBA模式的mask,保证渐变透明效果正确叠加

HTML/CSS/JS 解决方案

如果用前端实现,可以通过CSS伪元素+transform快速生成镜像效果,无需复杂绘制:

HTML

<div class="image-slicer">
  <div class="slice" style="background-image: url('image.jpeg'); background-position: 0% 0%"></div>
  <div class="slice" style="background-image: url('image.jpeg'); background-position: 33.33% 0%"></div>
  <div class="slice" style="background-image: url('image.jpeg'); background-position: 66.66% 0%"></div>
</div>

CSS

.image-slicer {
  display: flex;
  gap: 10px;
}

.slice {
  width: calc(100% / 3);
  height: 400px;
  background-size: 300% 100%;
  position: relative;
  overflow: visible;
}

.slice::after {
  content: '';
  position: absolute;
  top: 0;
  right: -20px;
  width: 20px;
  height: 100%;
  background-image: inherit;
  background-position: inherit;
  transform: translateX(100%) scaleX(-1);
  /* 添加渐变遮罩模拟透明效果 */
  mask: linear-gradient(to left, rgba(0,0,0,0), rgba(0,0,0,1));
  -webkit-mask: linear-gradient(to left, rgba(0,0,0,0), rgba(0,0,0,1));
}

说明

  • 通过background-position控制每个切片显示原图的对应区域
  • 伪元素::after生成右侧镜像,用scaleX(-1)水平翻转,再通过渐变遮罩实现透明过渡
  • 无需JS即可完成,响应式效果更好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:55:12