Photoshop 将版权符号保存为 UTF-8(未转义)在元数据中


Photoshop saves copyright symbol as UTF-8 (unescaped) in metadata

>**更新 - 我发现了这篇关于Photoshop编码的文章 - 说他们"以UTF-8编码将字符"©"编码为Exif元数据。

** 答案 - 这是一个转义问题 - 不是编码问题。Photoshop 允许元数据中的版权符号而不对其进行转义。这在上面的链接中提到(并抱怨)。我更改了标题以反映真正的问题**

我已经阅读了这个网站上的所有内容,试图将版权符号保存到 jpeg 元数据。我知道问题正在编码,并且已经尝试了一切。

问题:当我将版权符号保存到 jpeg 元数据时,它在 Photoshop 中显示为©,但是当我加载元数据时,它会正确输入。

写入 jpeg 时,我调用 UTF8_to_unicode_array() 对字符串进行编码,然后在保存之前调用 unicode_array_to_UTF8()。知道我错过了什么吗?

从 UTF8 到 unicode:

function UTF8_to_unicode_array($utf8_text )
{    
    // Create an array to receive the unicode character numbers output
    $output = array();
    mb_convert_encoding($utf8_text,'utf-8');                
    $atext = mbStringToArray($utf8_text);
// Cycle through the characters in the UTF-8 string
foreach ($atext as $text ){
    $output [] = uniord2($text);
}
return $output;
}
function uniord2($c)
  $ord0 = ord($c{0}); if ($ord0>=0   && $ord0<=127) return $ord0;
  $ord1 = ord($c{1}); if ($ord0>=192 && $ord0<=223) return ($ord0-192)*64 + ($ord1-128); 
  $ord2 = ord($c{2}); if ($ord0>=224 && $ord0<=239) return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128);
  $ord3 = ord($c{3}); if ($ord0>=240 && $ord0<=247) return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128);
return false;
}

function mbStringToArray ($string) {
  $array = array();
  $strlen = mb_strlen($string);
  while ($strlen) {
    $array[] = mb_substr($string,0,1,"UTF-8");
    $string = mb_substr($string,1,$strlen,"UTF-8");
    $strlen = mb_strlen($string);
}
return $array;
}

从 unicode 到 UTF8:

function unicode_array_to_UTF8( $unicode_array ){
    // Create a string to receive the UTF-8 output
    $output = "";
    // Cycle through each Unicode character number
    foreach( $unicode_array as $unicode_char )
    {
  $output .= utf8($unicode_char);
}
    // Return resulting UTF-8 String
    return $output;
}
function utf8($num){
  if($num<=0x7F)       return chr($num);        
  if($num<=0x7FF)      return chr(($num>>6)+192).chr(($num&63)+128);
  if($num<=0xFFFF)     return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
  if($num<=0x1FFFFF)   return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128).chr(($num&63)+128);
return '';
}

您需要找出 JPEG 数据使用的编码。如果Photoshop不使用该编码,它就有问题,您应该要求退还您的钱(并使用免费的替代方案,无论如何都更好)。如果您的代码需要处理损坏的JPEG元数据(例如,来自损坏的Photoshop),则必须猜测编码(可能是Latin-1或Latin-15)并相应地进行转码。

现在,

假设您现在知道编码,您可以将字节转码为 UTF-8(这是一种 Unicode 编码)以便在 PHP 中使用。请注意,PHP 并不特别支持 Unicode,它仍然使用字节字符串,因此 ASCII 范围之外的任何内容都将使用多个字符。在索引到此类字符串时请记住这一点。这也提出了一个问题,即"Unicode to UTF8"是什么意思,因为 UTF-8 Unicode。

我知道我在这里有点乐观,但很难说问题出在哪个地方。尝试诊断此问题时,请确保您始终知道正在处理的字符串的字节值。原因是显示总是涉及某种解释,这使得无法判断显示或内容是否是罪魁祸首。

不过,我仍然猜测您的问题在哪里,或者至少您可以解决其中一个问题:您的函数 uniord() 将消耗提供的字符串中可变数量的字节。如果单个字符(如版权标志)占用两个字节,您将解码该字符,然后在下一步中再次解码该字符的第二个字节,这只会产生垃圾。实际上,尝试将延续字节(二进制中的 10xxxxxx)解码为 UTF-8 序列中的第一个字节应该会引发异常,因为这是您没有有效 UTF-8 的明确信号。帮自己一个忙,检查这些错误并大声发出信号!