You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python读取.EMF格式图片及批量读取文件夹内图片

处理EMF格式图片的Python实现

为什么PIL无法直接打开EMF?

Pillow(PIL)本身不支持**EMF(增强型元文件)**格式,这是Windows专属的矢量图格式,必须先将其转换为PNG/JPEG等光栅图格式,才能用Pillow读取处理。


单张EMF图片转换与读取代码

方案一:Windows环境专属(依赖pywin32)

该方案利用Windows系统的GDI接口直接绘制EMF并转换为PIL图像,无需额外安装第三方工具。

  1. 先安装依赖:
pip install pywin32
  1. 实现代码:
import win32api
import win32ui
import win32con
import win32gui
from PIL import Image
import numpy as np

def load_emf_as_pil_image(emf_path):
    # 加载EMF文件
    emf_handle = win32api.LoadImage(0, emf_path, win32con.IMAGE_ENHMETAFILE, 0, 0, win32con.LR_LOADFROMFILE)
    if not emf_handle:
        raise Exception(f"无法加载EMF文件: {emf_path}")
    
    # 获取EMF的宽高
    emf_bits = win32api.GetEnhMetaFileBits(emf_handle)
    width = int.from_bytes(emf_bits[40:44], byteorder='little')
    height = int.from_bytes(emf_bits[44:48], byteorder='little')
    
    # 创建设备上下文与兼容位图
    hdc = win32ui.CreateDC()
    hdc.CreateCompatibleDC()
    bmp = win32ui.CreateBitmap()
    bmp.CreateCompatibleBitmap(hdc, width, height)
    hdc.SelectObject(bmp)
    
    # 将EMF绘制到位图上
    win32gui.PlayEnhMetaFile(hdc.GetSafeHdc(), emf_handle, (0, 0, width, height))
    
    # 转换为PIL图像
    bmp_info = bmp.GetInfo()
    bmp_str = bmp.GetBitmapBits(True)
    pil_img = Image.frombuffer('RGB', (bmp_info['bmWidth'], bmp_info['bmHeight']), bmp_str, 'raw', 'BGRX', 0, 1)
    
    # 释放系统资源
    win32api.DeleteEnhMetaFile(emf_handle)
    hdc.DeleteDC()
    bmp.DeleteObject()
    
    return pil_img

# 使用示例
if __name__ == "__main__":
    emf_path = "image/test_image.emf"
    try:
        img = load_emf_as_pil_image(emf_path)
        # 转换为numpy数组(和你处理JPEG/PNG的方式一致)
        img_np = np.array(img)
        # 保存为PNG
        img.save("converted_image.png")
        print("处理成功")
    except Exception as e:
        print(f"错误: {e}")

方案二:跨平台方案(依赖ImageMagick + wand)

该方案支持Windows、Linux、macOS,需要额外安装ImageMagick工具。

  1. 安装步骤:

    • 下载并安装ImageMagick,安装时勾选Add application directory to your system path
    • 安装Python库:
    pip install wand
    
  2. 实现代码:

from wand.image import Image as WandImage
from PIL import Image
import numpy as np
import io

def emf_to_pil_image(emf_path):
    with WandImage(filename=emf_path) as wand_img:
        # 将EMF转换为PNG字节流
        wand_img.format = 'png'
        png_bytes = wand_img.make_blob()
    # 用PIL读取字节流
    pil_img = Image.open(io.BytesIO(png_bytes))
    return pil_img

# 使用示例
if __name__ == "__main__":
    emf_path = "image/test_image.emf"
    try:
        img = emf_to_pil_image(emf_path)
        img_np = np.array(img)
        img.save("converted_image.png")
        print("处理成功")
    except Exception as e:
        print(f"错误: {e}")

批量读取文件夹中所有EMF图片

结合上面的转换函数,遍历文件夹筛选.emf后缀文件并批量处理:

import os

# 这里替换成你使用的转换函数(比如load_emf_as_pil_image或emf_to_pil_image)
from emf_converter import load_emf_as_pil_image

def process_all_emf(folder_path):
    # 筛选所有.emf后缀文件(不区分大小写)
    emf_files = [
        f for f in os.listdir(folder_path)
        if f.lower().endswith('.emf')
    ]
    
    for emf_file in emf_files:
        emf_full_path = os.path.join(folder_path, emf_file)
        try:
            img = load_emf_as_pil_image(emf_full_path)
            # 这里添加你的处理逻辑,比如保存、分析等
            output_path = os.path.splitext(emf_full_path)[0] + '.png'
            img.save(output_path)
            print(f"已处理: {emf_file}")
        except Exception as e:
            print(f"处理失败 {emf_file}: {e}")

# 使用示例
if __name__ == "__main__":
    target_folder = "image"
    process_all_emf(target_folder)

内容的提问来源于stack exchange,提问作者user18948968

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:39:51