如何用Python读取.EMF格式图片及批量读取文件夹内图片
处理EMF格式图片的Python实现
为什么PIL无法直接打开EMF?
Pillow(PIL)本身不支持**EMF(增强型元文件)**格式,这是Windows专属的矢量图格式,必须先将其转换为PNG/JPEG等光栅图格式,才能用Pillow读取处理。
单张EMF图片转换与读取代码
方案一:Windows环境专属(依赖pywin32)
该方案利用Windows系统的GDI接口直接绘制EMF并转换为PIL图像,无需额外安装第三方工具。
- 先安装依赖:
pip install pywin32
- 实现代码:
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工具。
安装步骤:
- 下载并安装ImageMagick,安装时勾选Add application directory to your system path
- 安装Python库:
pip install wand实现代码:
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
相关产品推荐
相关产品推荐

