first commit
This commit is contained in:
81
image_test/extract_docx_images.py
Normal file
81
image_test/extract_docx_images.py
Normal file
@@ -0,0 +1,81 @@
|
||||
"""从 docx 提取所有内嵌图片,方便定位实际插入到文档里的图片字节。
|
||||
|
||||
用法:
|
||||
python image_test/extract_docx_images.py <signed.docx>
|
||||
|
||||
输出:
|
||||
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 <signed.docx>")
|
||||
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()
|
||||
Reference in New Issue
Block a user