from PIL import Image, ImageDraw
import numpy as np
import os
import random


def generate_jigsaw_shape(piece_width, piece_height, variation=10):
    """
    生成拼图块的曲线边界。
    :param piece_width: 每块拼图的宽度。
    :param piece_height: 每块拼图的高度。
    :param variation: 曲线的随机偏移量。
    :return: 拼图块的路径点列表。
    """
    points = []
    for x in range(0, piece_width + 1):
        y = piece_height // 2 + random.randint(-variation, variation)
        points.append((x, y))
    for y in range(piece_height, -1, -1):
        x = piece_width // 2 + random.randint(-variation, variation)
        points.append((x, y))
    return points


def create_jigsaw_pieces(image_path, output_dir, rows=5, cols=5, variation=10):
    """
    使用曲线形状将图片裁剪成拼图块。
    :param image_path: 输入图片路径。
    :param output_dir: 输出拼图块的保存目录。
    :param rows: 拼图的行数。
    :param cols: 拼图的列数。
    :param variation: 拼图曲线的随机偏移量。
    """
    # 打开图片
    img = Image.open(image_path)
    img_width, img_height = img.size

    # 每块的宽和高
    piece_width = img_width // cols
    piece_height = img_height // rows

    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    for row in range(rows):
        for col in range(cols):
            # 定义裁剪区域
            left = col * piece_width
            upper = row * piece_height
            right = (col + 1) * piece_width
            lower = (row + 1) * piece_height

            # 生成随机曲线形状
            points = generate_jigsaw_shape(piece_width, piece_height, variation)

            # 创建掩码
            mask = Image.new("L", (piece_width, piece_height), 0)
            draw = ImageDraw.Draw(mask)
            draw.polygon(points, fill=255)

            # 裁剪拼图块
            piece = img.crop((left, upper, right, lower))
            piece.putalpha(mask)

            # 保存拼图块
            piece_path = os.path.join(output_dir, f"piece_{row}_{col}.png")
            piece.save(piece_path, "PNG")

    print(f"拼图已生成，保存在：{output_dir}")


# 示例调用
image_path = "input.jpg"  # 输入图片路径
output_dir = "output_jigsaw"  # 输出目录
create_jigsaw_pieces(image_path, output_dir, rows=5, cols=5, variation=15)
