# -*- coding: utf-8 -*- """ 切割漫画格子图片 """ import sys import json import cv2 import numpy as np from pathlib import Path # Windows编码修复 if sys.platform == 'win32': import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') def cut_panels(image_path, panels_json_path, output_dir): """ 切割漫画格子图片 参数: image_path: 原始图片路径 panels_json_path: 格子信息JSON文件路径 output_dir: 输出目录 """ image_path = Path(image_path) panels_json_path = Path(panels_json_path) output_dir = Path(output_dir) output_dir.mkdir(parents=True, exist_ok=True) # 读取原始图片 print(f"📖 读取原始图片: {image_path.name}") img_array = np.fromfile(str(image_path), dtype=np.uint8) img = cv2.imdecode(img_array, cv2.IMREAD_COLOR) if img is None: raise ValueError(f"无法读取图片: {image_path}") img_height, img_width = img.shape[:2] print(f"[INFO] 图片尺寸: {img_width}x{img_height}") # 读取格子信息 print(f"📋 读取格子信息: {panels_json_path.name}") with open(panels_json_path, 'r', encoding='utf-8') as f: panels_data = json.load(f) panels = panels_data.get('panels', []) if len(panels) == 0: raise ValueError("未找到任何格子信息") print(f"[INFO] 找到 {len(panels)} 个格子") # 按照从右到左、从上到下的顺序排序格子 sorted_panels = sorted(panels, key=lambda p: (p['center_y'], -p['center_x'])) # 切割每个格子 for idx, panel in enumerate(sorted_panels, 1): x = max(0, int(panel['x'])) y = max(0, int(panel['y'])) w = min(int(panel['width']), img_width - x) h = min(int(panel['height']), img_height - y) if w <= 0 or h <= 0: print(f"[WARN] 跳过无效格子 {idx}: x={x}, y={y}, w={w}, h={h}") continue # 切割格子区域 panel_img = img[y:y+h, x:x+w] # 保存切割后的图片 output_filename = f"check{idx}.png" output_path = output_dir / output_filename # 使用cv2.imencode处理中文路径 success, encoded_img = cv2.imencode('.png', panel_img) if success: encoded_img.tofile(str(output_path)) print(f" [{idx}/{len(sorted_panels)}] 已保存: {output_filename} ({w}x{h})") else: print(f"[ERROR] 保存失败: {output_filename}") print(f"\n✅ 切割完成,共 {len(sorted_panels)} 个格子") if __name__ == '__main__': if len(sys.argv) < 4: print("用法: python cut_panels.py <原始图片路径> <格子信息JSON路径> <输出目录>") sys.exit(1) image_path = sys.argv[1] panels_json_path = sys.argv[2] output_dir = sys.argv[3] try: cut_panels(image_path, panels_json_path, output_dir) except Exception as e: print(f"[ERROR] 切割失败: {e}") import traceback traceback.print_exc() sys.exit(1)