mcpField
I
image-metadata-tool

image-metadata-tool

github.com/dkyazzentwatwa创意与媒体12468 次安装29 周前更新
代码仓库

关于 image-metadata-tool

image-metadata-tool 是用于提取和管理图像 EXIF 数据的 Python 库及命令行工具,适合整理照片和检查隐私。它支持批量分析、GPS 地图生成及元数据移除。

主要功能

  1. 01提取相机、设置、时间戳和尺寸
  2. 02读取 GPS 坐标并映射地点
  3. 03移除元数据,可保留方向信息
  4. 04批量处理图像文件夹
  5. 05导出 JSON、CSV 和 HTML 报告

适用场景

  1. 01按日期和相机整理导入的照片
  2. 02分享前检查照片是否含有位置数据
  3. 03为带地理标记的旅行照片生成交互地图

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dkyazzentwatwa/chatgpt-skills --skill image-metadata-tool

安装后在 Claude Code 中输入/image-metadata-tool确认已加载。

附带文件scripts/image_metadata.pyscripts/requirements.txt

详细介绍

图像元数据工具

提取、分析和管理图像的 EXIF 元数据,并支持 GPS 映射和隐私保护功能。

功能

  • EXIF 提取:相机、镜头、设置、时间戳
  • GPS 数据:提取坐标、在地图上标记位置
  • 元数据移除:清除 EXIF,保护隐私
  • 批量处理:处理多张图像
  • 地图生成:根据照片创建位置地图
  • 导出:JSON、CSV、HTML 报告

快速开始

from image_metadata import ImageMetadata

meta = ImageMetadata()
meta.load("photo.jpg")

# Get all metadata
info = meta.extract()
print(f"Camera: {info['camera']}")
print(f"Date: {info['datetime']}")

# Get GPS coordinates
gps = meta.get_gps()
if gps:
    print(f"Location: {gps['latitude']}, {gps['longitude']}")

CLI 用法

# Extract metadata
python image_metadata.py --input photo.jpg

# Extract with GPS info
python image_metadata.py --input photo.jpg --gps

# Batch extract from folder
python image_metadata.py --input ./photos/ --output metadata.csv

# Generate location map
python image_metadata.py --input ./photos/ --map locations.html

# Strip metadata (create clean copy)
python image_metadata.py --input photo.jpg --strip --output clean_photo.jpg

# Batch strip metadata
python image_metadata.py --input ./photos/ --strip --output ./clean_photos/

# JSON output
python image_metadata.py --input photo.jpg --json

# Get specific fields
python image_metadata.py --input photo.jpg --fields camera,datetime,gps,dimensions

API 参考

ImageMetadata 类
class ImageMetadata:
    def __init__(self)

    # Loading
    def load(self, filepath: str) -> 'ImageMetadata'

    # Extraction
    def extract(self) -> dict
    def get_camera_info(self) -> dict
    def get_datetime(self) -> dict
    def get_gps(self) -> dict
    def get_dimensions(self) -> dict
    def get_all_exif(self) -> dict

    # Privacy
    def strip_metadata(self, output: str, keep_orientation: bool = True) -> str
    def has_location(self) -> bool

    # Batch operations
    def extract_batch(self, folder: str, recursive: bool = False) -> list
    def strip_batch(self, input_folder: str, output_folder: str) -> list

    # Maps
    def generate_map(self, images: list, output: str) -> str

    # Export
    def to_json(self, output: str) -> str
    def to_csv(self, output: str) -> str

提取的元数据

相机信息
camera_info = meta.get_camera_info()

# Returns:
{
    "make": "Canon",
    "model": "EOS R5",
    "lens": "RF 24-70mm F2.8 L IS USM",
    "lens_id": "61",
    "software": "Adobe Photoshop 24.0",
    "serial_number": "012345678901"
}
拍摄设置
settings = meta.extract()["settings"]

# Returns:
{
    "exposure_time": "1/250",
    "f_number": 2.8,
    "iso": 400,
    "focal_length": 50,
    "focal_length_35mm": 50,
    "exposure_program": "Aperture priority",
    "metering_mode": "Pattern",
    "flash": "No flash",
    "white_balance": "Auto"
}
GPS 数据
gps = meta.get_gps()

# Returns:
{
    "latitude": 37.7749,
    "longitude": -122.4194,
    "altitude": 10.5,
    "altitude_ref": "Above sea level",
    "timestamp": "2024-01-15 14:30:00",
    "direction": 180.5,
    "speed": 0,
    "maps_url": "https://maps.google.com/maps?q=37.7749,-122.4194"
}
时间戳
datetime_info = meta.get_datetime()

# Returns:
{
    "original": "2024-01-15 14:30:00",
    "digitized": "2024-01-15 14:30:00",
    "modified": "2024-01-16 10:00:00",
    "timezone": "+00:00"
}
图像尺寸
dims = meta.get_dimensions()

# Returns:
{
    "width": 8192,
    "height": 5464,
    "megapixels": 44.8,
    "orientation": "Horizontal",
    "resolution_x": 300,
    "resolution_y": 300,
    "resolution_unit": "inch"
}

完整输出

info = meta.extract()

# Returns:
{
    "file": {
        "name": "IMG_1234.jpg",
        "path": "/photos/IMG_1234.jpg",
        "size": 15234567,
        "format": "JPEG"
    },
    "camera": {
        "make": "Canon",
        "model": "EOS R5",
        "lens": "RF 24-70mm F2.8 L IS USM"
    },
    "settings": {
        "exposure_time": "1/250",
        "f_number": 2.8,
        "iso": 400,
        "focal_length": 50
    },
    "datetime": {
        "original": "2024-01-15 14:30:00"
    },
    "gps": {
        "latitude": 37.7749,
        "longitude": -122.4194
    },
    "dimensions": {
        "width": 8192,
        "height": 5464
    }
}

隐私功能

清除元数据

移除 EXIF 数据以保护隐私:

# Strip all metadata
meta.load("original.jpg")
meta.strip_metadata("clean.jpg")

# Keep orientation (prevents rotated images)
meta.strip_metadata("clean.jpg", keep_orientation=True)
检查位置数据
meta.load("photo.jpg")
if meta.has_location():
    print("Warning: Photo contains GPS coordinates!")
批量清除
meta.strip_batch("./originals/", "./cleaned/")

GPS 映射

生成位置地图

根据带有地理标记的照片创建交互式地图:

meta = ImageMetadata()

# Batch extract with GPS
images = meta.extract_batch("./vacation_photos/")

# Filter to only geotagged images
geotagged = [img for img in images if img.get("gps")]

# Generate map
meta.generate_map(geotagged, "photo_map.html")

地图包括:

  • 每张照片位置的标记
  • 带有照片缩略图和元数据的弹出窗口
  • 密集区域的聚类显示

批量处理

从文件夹提取
meta = ImageMetadata()

# All images in folder
results = meta.extract_batch("./photos/")

# Recursive (include subfolders)
results = meta.extract_batch("./photos/", recursive=True)

# Export to CSV
df = pd.DataFrame(results)
df.to_csv("metadata.csv", index=False)
按条件筛选
results = meta.extract_batch("./photos/")

# Find high ISO photos
high_iso = [r for r in results if r.get("settings", {}).get("iso", 0) > 3200]

# Find photos from specific camera
canon_photos = [r for r in results if "Canon" in r.get("camera", {}).get("make", "")]

# Find photos with GPS
geotagged = [r for r in results if r.get("gps")]

示例工作流

照片整理
meta = ImageMetadata()
results = meta.extract_batch("./camera_import/")

for photo in results:
    date = photo.get("datetime", {}).get("original", "unknown")
    camera = photo.get("camera", {}).get("model", "unknown")
    print(f"{photo['file']['name']}: {date} - {camera}")
隐私审计
meta = ImageMetadata()
results = meta.extract_batch("./to_share/")

risky = []
for photo in results:
    if photo.get("gps"):
        risky.append({
            "file": photo["file"]["name"],
            "location": f"{photo['gps']['latitude']}, {photo['gps']['longitude']}"
        })

if risky:
    print(f"Warning: {len(risky)} photos contain location data!")
    for r in risky:
        print(f"  - {r['file']}: {r['location']}")
旅行照片地图
meta = ImageMetadata()
results = meta.extract_batch("./trip_photos/", recursive=True)

# Generate interactive map
geotagged = [r for r in results if r.get("gps")]
print(f"Found {len(geotagged)} geotagged photos")

meta.generate_map(geotagged, "trip_map.html")

支持的格式

  • JPEG/JPG(完整支持 EXIF)
  • TIFF(完整支持 EXIF)
  • PNG(元数据支持有限)
  • HEIC/HEIF(iOS 照片)
  • WebP(元数据支持有限)
  • RAW 格式(CR2、NEF、ARW 等)

依赖项

  • pillow>=10.0.0
  • folium>=0.14.0(用于生成地图)

评论

支持 Markdown