"""从 docx 提取所有内嵌图片,方便定位实际插入到文档里的图片字节。 用法: python image_test/extract_docx_images.py 输出: image_test/output/docx_images/<图片名>.png (按 docx 内顺序编号) 每张图打印尺寸 + 紧致度诊断 """ import io import sys import zipfile from pathlib import Path from PIL import Image, ImageChops BASE_DIR = Path(__file__).resolve().parent OUT_DIR = BASE_DIR / "output" / "docx_images" def analyze_image(data): img = Image.open(io.BytesIO(data)) if img.mode != 'RGBA': img = img.convert('RGBA') r, g, b, a = img.split() luma = Image.merge('RGB', (r, g, b)).convert('L') alpha_mask = a.point(lambda p: 255 if p > 30 else 0) luma_mask = luma.point(lambda p: 255 if p < 210 else 0) combined = ImageChops.darker(alpha_mask, luma_mask) total = img.size[0] * img.size[1] or 1 return { 'size': img.size, 'mode': img.mode, 'content_pct': 100.0 * sum(combined.histogram()[1:]) / total, 'bbox': combined.getbbox(), 'alpha_pct': 100.0 * sum(alpha_mask.histogram()[1:]) / total, } def main(): if len(sys.argv) < 2: print("用法: python image_test/extract_docx_images.py ") sys.exit(1) docx_path = Path(sys.argv[1]) if not docx_path.exists(): print(f"文件不存在: {docx_path}") sys.exit(1) OUT_DIR.mkdir(parents=True, exist_ok=True) with zipfile.ZipFile(docx_path, 'r') as z: media_files = sorted([n for n in z.namelist() if n.startswith('word/media/')]) if not media_files: print("docx 内未找到 word/media/ 下的图片") return print(f"找到 {len(media_files)} 张图片\n") for i, name in enumerate(media_files, 1): data = z.read(name) ext = Path(name).suffix or '.png' out_path = OUT_DIR / f"image_{i:02d}{ext}" with open(out_path, 'wb') as f: f.write(data) try: stats = analyze_image(data) print(f"[{i:02d}] {name}") print(f" 尺寸={stats['size']} 模式={stats['mode']} " f"alpha像素={stats['alpha_pct']:.1f}% " f"内容={stats['content_pct']:.1f}% bbox={stats['bbox']}") print(f" 已保存: {out_path}") except Exception as e: print(f"[{i:02d}] {name}: 解析失败 {e}") print() if __name__ == '__main__': main()