php Imagick是否读取iPhone Exif:方向错误?

bq8i3lrv  于 2023-01-16  发布在  PHP
关注(0)|答案(1)|浏览(120)

我试着用php自动旋转一些压缩文件中的图片。对于自动旋转,我使用的是Exif:图片的方向信息。
代码确实工作,但我有一些图像的问题,似乎有错误的exif信息。我有这个问题,只有与图像采取的iPhone。
我的准则的作用:
1.把图片从拉链里拉出来
1.保存这pic在一个临时文件为.png处理
1.用1中的图片字符串初始化一个imagick对象。
1.检查pic是否为png

  1. is png:通过帮助器类PNGMetadata读取exif方向
    1.不是png:使用imagick imageproperty得到exif方向
    1.调用autoRotateImage将图片转到正确的方向
    1.保存原始方向以备后用(我正在将原始方向保存在数据库中以供调试)
    函数“autoRotateImage”仅处理exif方向并对每个方向执行正确的步骤。
    PHP代码的组成部分:
try{
$img_content = $zip->getFromIndex($zip->locateName($img->getAttribute('xlink:href')));
$tmpPic = tempnam(sys_get_temp_dir(), $img->getAttribute('xlink:href'));
file_put_contents($tmpPic,$img_content);
$imagick_img = new \Imagick();
$imagick_img->readImageBlob($img_content);
if (PNGMetadata::isPNG($tmpPic)){
  $png_metadata = new PNGMetadata($tmpPic);
  $orientation_arr[$img->getAttribute('xlink:href')] = $png_metadata->get('exif:IFD0:Orientation');
  $org_orientation = $png_metadata->get('exif:IFD0:Orientation');
}else{
  $orientation_arr[$img->getAttribute('xlink:href')] = intval($imagick_img->getImageProperty('Exif:Orientation'));
  $org_orientation = intval($imagick_img->getImageProperty('Exif:Orientation'));
}
autoRotateImage($imagick_img,new \Imagick(),(isset($manualOrientation[$img->getAttribute('xlink:href')]) ? $manualOrientation[$img->getAttribute('xlink:href')] : $org_orientation));
$imagick_img->clear();
unlink($tmpPic);
}catch(Exception $e){
  if(isset($imagick_img)){$imagick_img->clear();}
  if(isset($tmpPic)){unlink($tmpPic);}
}

自动旋转图像功能:

function autoRotateImage(&$image, $imagick, $orientation) {
        switch($orientation) {
            case $imagick::ORIENTATION_BOTTOMRIGHT: //3
                $image->rotateimage("#000", 180); // rotate 180 degrees
                break;

            case $imagick::ORIENTATION_BOTTOMLEFT: //4
                $image->flipImage(); // mirror vertical
                break;
    
            case $imagick::ORIENTATION_RIGHTTOP: //6
                $image->rotateimage("#000", 90); // rotate 90 degrees CW
                break;

             case $imagick::ORIENTATION_LEFTTOP: //5
                $image->transverseImage(); // horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
                break;
    
            case $imagick::ORIENTATION_LEFTBOTTOM: //8
                $image->rotateimage("#000", 270); // rotate 270 degrees CW
                break;

            case $imagick::ORIENTATION_RIGHTBOTTOM: //7
                $image->transverseImage();      //horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
                $image->rotateimage("#000", -180); // rotate 180 degrees CCW
                break;

            case $imagick::ORIENTATION_TOPLEFT: //1
                //Nothing to do
                break;

            case $imagick::ORIENTATION_TOPRIGHT: //2
                $image->transverseImage();      //horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
                $image->rotateimage("#000", 90); // rotate 90 degrees CW
                break;
        }

        // Now that it's auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image!
        $image->setImageOrientation($imagick::ORIENTATION_TOPLEFT);
    }

类“PNGMetadata”来自其他用户:https://github.com/joserick/PNGMetadata
所以..此代码适用于90%的处理图像,除了一些iPhone图像。当前案例:Exif方向显示为5(在y轴上镜像并顺时针旋转270),但它应该为7(在y轴上镜像并顺时针旋转90)
也许有人知道如何处理这些案件?
我已经尝试过以其他形式获取exif信息,但结果每次都是一样的。还有一个命令行exif阅读器从错误的图像中读到了错误的exif方向。
我需要一种方法来修复错误的方向。

osh3o9ms

osh3o9ms1#

看起来imagick函数“transverseImage()”并不像aspected那样工作..我不知道它的确切功能,但我认为它的行为不符合描述..
描述说“创建一个水平镜像反射像素周围的中心y轴,同时旋转他们270度。"对我来说,这意味着,图像得到镜像,然后旋转270°CW。但图像将错误旋转后,该函数。
我尝试将“Imagick::flopImage”与rotateImage(270)结合使用,得到了不同的结果。
简短:我用flopImage + rotateImage替换了transverseImage,现在看来,图像旋转正确。

相关问题