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

PHP读取图片EXIF/IPTC元数据出现乱码问题排查与解决

读取图片EXIF和IPTC元数据时出现乱码的原因及解决方法

问题背景

我尝试读取图片的EXIF和IPTC元数据,但部分内容显示为一串?乱码,怀疑是编码问题但不确定。

复现代码

<?php

$path = 'no_exif.jpg';

$exif = @exif_read_data($path, '', true);
var_dump($exif);

getimagesize($path, $image_info);
foreach($image_info as $k => $v) {
    
    var_dump($k);

    if ($k === 'APP13') {
        var_dump(iptcparse($v));
    } else {
        var_dump ($v);
    }
}

测试情况

测试图片包含XPTitle等标签,在线元数据解析工具可正常读取,但本地PHP代码输出乱码。我曾尝试用自动检测编码转UTF-8,但没有效果:

array_walk_recursive($entries, function (&$entry) {
    $source_encoding = mb_detect_encoding($entry);
    $source_encoding = ($source_encoding) ? ($source_encoding) : 'ISO-8859-1';
    $entry = mb_convert_encoding($entry, 'UTF-8', $source_encoding);
});

乱码原因

  1. XP系列标签的特殊编码:微软定义的XPTitle、XPComment等EXIF标签,使用UTF-16LE编码存储,但PHP的exif_read_data默认按单字节编码(如ISO-8859-1)读取,直接输出就会显示为乱码或问号。
  2. 自动编码检测失效:mb_detect_encoding无法准确识别UTF-16LE的字节特征,导致转码时用错源编码,无法修复乱码。
  3. IPTC元数据的编码默认值:IPTC数据通常采用ISO-8859-1编码,若按其他编码读取也会出现乱码。

解决方法

1. 修复XP系列标签的编码

直接指定源编码为UTF-16LE转码,同时处理可能存在的BOM:

function fixExifXPTags($exifData) {
    // 定义需要修复的XP标签列表
    $xpTagNames = ['XPTitle', 'XPComment', 'XPAuthor', 'XPKeywords', 'XPSubject'];
    
    foreach ($xpTagNames as $tag) {
        if (isset($exifData['IFD0'][$tag])) {
            $rawValue = $exifData['IFD0'][$tag];
            // 移除UTF-16的BOM(LE或BE)
            $rawValue = preg_replace('/^\xFE\xFF|\xFF\xFE/', '', $rawValue);
            // 转码为UTF-8
            $exifData['IFD0'][$tag] = mb_convert_encoding($rawValue, 'UTF-8', 'UTF-16LE');
        }
    }
    return $exifData;
}

// 使用示例
$path = 'no_exif.jpg';
$exif = @exif_read_data($path, '', true);
$fixedExif = fixExifXPTags($exif);
var_dump($fixedExif);

2. 处理IPTC元数据编码

IPTC数据默认用ISO-8859-1编码,直接指定转码:

getimagesize($path, $image_info);
foreach($image_info as $k => $v) {
    if ($k === 'APP13') {
        $iptcData = iptcparse($v);
        // 递归转码所有IPTC内容
        array_walk_recursive($iptcData, function (&$entry) {
            $entry = mb_convert_encoding($entry, 'UTF-8', 'ISO-8859-1');
        });
        var_dump($iptcData);
    } else {
        var_dump($v);
    }
}

3. 环境检查

确保PHP的mbstring扩展已启用,这是转码函数正常工作的前提。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:35:29