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

如何使用PIL读取Windows Shell Namespace路径文件的元数据?

解决PIL无法打开Windows Shell Namespace路径文件的问题

问题原因

Python标准库的builtins.open()(也就是PIL底层依赖的文件打开方式)只能识别常规本地文件系统路径,无法解析Windows Shell Namespace这类虚拟路径(比如你提供的iPhone设备图片路径)。这类路径是Windows Shell特有的虚拟命名空间,只有Windows资源管理器这类调用Shell API的程序才能直接访问。

解决方案

要处理这类路径,需要借助Windows Shell API来获取文件的真实路径或文件流,再传递给PIL。以下是两种可行方法:

方法一:通过pywin32获取文件流直接打开

使用pywin32库调用Windows Shell API解析路径,获取文件流后用PIL打开:

  1. 先安装依赖:
    pip install pywin32
    
  2. 示例代码:
    import win32com.client
    from PIL import Image
    import io
    
    # 去掉路径两端引号,处理转义
    shell_path = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\{55DE1ED1-3F3E-4C88-BC1A-819EFF0BE330}\\73cdac9ad5200bebf6ab95998c1bed571f70fd23\\PhotoLibrary\\photo_library.album.all_assets\\A2FD049A03544E90B70243069CB28014.JPG"
    
    # 初始化Shell对象
    shell = win32com.client.Dispatch("Shell.Application")
    # 解析Shell路径获取文件项
    file_item = shell.Namespace(0).ParseName(shell_path)
    
    try:
        # 优先尝试获取真实文件路径(部分虚拟路径可能有映射的真实路径)
        real_file_path = file_item.Path
        with Image.open(real_file_path) as img:
            exif_data = img.getexif()
            # 处理EXIF信息,示例为打印
            print(exif_data)
    except Exception:
        # 若无法获取真实路径,直接读取文件流
        file_stream = file_item.GetLink()
        if file_stream:
            # 将流写入内存字节对象
            stream_content = io.BytesIO(file_stream.Read())
            with Image.open(stream_content) as img:
                exif_data = img.getexif()
                print(exif_data)
        else:
            print("无法获取文件的真实路径或流")
    

方法二:复制文件到临时目录再处理

如果上述方法无法获取流,可将Shell命名空间中的文件复制到本地临时目录,再用PIL打开:

import win32com.client
import tempfile
import os
from PIL import Image

shell_path = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\{55DE1ED1-3F3E-4C88-BC1A-819EFF0BE330}\\73cdac9ad5200bebf6ab95998c1bed571f70fd23\\PhotoLibrary\\photo_library.album.all_assets\\A2FD049A03544E90B70243069CB28014.JPG"

shell = win32com.client.Dispatch("Shell.Application")
file_item = shell.Namespace(0).ParseName(shell_path)

# 创建临时目录,生成临时文件路径
temp_dir = tempfile.gettempdir()
temp_file_path = os.path.join(temp_dir, file_item.Name)

# 复制Shell中的文件到临时目录
shell.Namespace(temp_dir).CopyHere(file_item)

# 用PIL打开临时文件并读取EXIF
with Image.open(temp_file_path) as img:
    exif_data = img.getexif()
    print(exif_data)

# 处理完成后删除临时文件
os.remove(temp_file_path)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:45:25