import cv2
import numpy as np
import os

def create_vertical_scroll_images_with_fixed_area_cv(input_path, output_prefix, height=128, fixed_width=8, fixed_height=16):
    """
    使用 OpenCV 实现：
    - 读取一张 128x128 图像
    - 生成 128 帧：每帧向上循环滚动 i 像素（顶部移到底部），但右下角固定区域不滚动
    - 每帧保存为单独的图片，命名为 output_prefix_i.png
    """
    # 1. 读取图像（OpenCV 默认 BGR）
    img = cv2.imread(input_path)
    if img is None:
        raise FileNotFoundError(f"无法读取图像: {input_path}")
    
    h, w = img.shape[:2]
    if h != height or w != height:
        raise ValueError(f"图像必须是 {height}x{height}，当前尺寸: {w}x{h}")

    # 确保输出目录存在
    output_dir = os.path.dirname(output_prefix)
    if output_dir and not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # 固定区域的坐标范围
    fixed_x_start = w - fixed_width
    fixed_y_start = h - fixed_height

    # 2. 循环生成滚动后的图像并保存
    for i in range(height):
        # 复制原图以保留固定区域
        rolled = img.copy()
        
        # 计算滚动部分的切片索引
        top_part = img[0:h-fixed_height, :]
        bottom_part_except_fixed = img[h-fixed_height:, 0:fixed_x_start]

        # 向上滚动 i 像素：使用 np.roll(axis=0, shift=-i)
        rolled_top = np.roll(top_part, shift=-i, axis=0)
        rolled_bottom_except_fixed = np.roll(bottom_part_except_fixed, shift=-i, axis=0)

        # 替换原图中的对应部分
        rolled[0:h-fixed_height, :] = rolled_top
        rolled[h-fixed_height:, 0:fixed_x_start] = rolled_bottom_except_fixed
        
        # 构建输出文件路径
        output_file = f"{output_prefix}_{i+1}.png"
        
        # 保存图像
        success = cv2.imwrite(output_file, rolled)
        if success:
            print(f"✅ 已保存: {output_file}")
        else:
            print(f"❌ 保存失败: {output_file}")

# ======================
# 使用示例
# ======================
if __name__ == "__main__":
    # 定义前缀和输入路径
    prefix = "gardvoid"  # 可根据需要更改
    input_path = "input.png"  # 输入图像路径
    output_prefix = f"./output/{prefix}"  # 输出图像前缀路径
    
    # 创建输出目录（如果不存在）
    if not os.path.exists("./output"):
        os.makedirs("./output")
    
    create_vertical_scroll_images_with_fixed_area_cv(
        input_path=input_path,
        output_prefix=output_prefix,
        height=128,
        fixed_width=8,
        fixed_height=16
    )
