如何停止 PHP iMagick 基于 EXIF“方向”数据自动旋转图像

2022-08-30 15:56:14

目前与PHP和iMagick合作开发海报打印Web应用程序。

这是我用来测试应用程序的上传/图像编辑功能的示例图像:

alt text

该映像包含以下 EXIF 数据:

[FileName] => 1290599108_IMG_6783.JPG
    [FileDateTime] => 1290599109
    [FileSize] => 4275563
    [FileType] => 2
    [MimeType] => image/jpeg
    [SectionsFound] => ANY_TAG, IFD0, THUMBNAIL, EXIF, INTEROP, MAKERNOTE
    [COMPUTED] => Array
        (
            [html] => width="3504" height="2336"
            [Height] => 2336
            [Width] => 3504
            [IsColor] => 1
            [ByteOrderMotorola] => 0
            [CCDWidth] => 22mm
            [ApertureFNumber] => f/5.6
            [UserComment] => 
            [UserCommentEncoding] => UNDEFINED
            [Thumbnail.FileType] => 2
            [Thumbnail.MimeType] => image/jpeg
        )

    [Make] => Canon
    [Model] => Canon EOS 30D
    [Orientation] => 6
    [XResolution] => 72/1
    [YResolution] => 72/1
    [ResolutionUnit] => 2
    [DateTime] => 2009:08:31 08:23:49
    [YCbCrPositioning] => 2
    [Exif_IFD_Pointer] => 196

但是 - iMagick,当使用此图像__construct时,会根据CCW自动将其旋转90度(我认为!导致此...[Orientation] => 6

alt text

我想知道的是...

如何保持页面顶部显示的图像的原始方向?这是否可以通过禁用iMagick执行的自动旋转来实现?

非常感谢

更新:这是我想出的解决方案...它将根据 EXIF 数据中的方向修复方向

   public function fixOrientation() {

       $exif = exif_read_data($this->imgSrc);
       $orientation = $exif['Orientation'];
       switch($orientation) {

           case 6: // rotate 90 degrees CW
               $this->image->rotateimage("#FFF", 90);
           break;

           case 8: // rotate 90 degrees CCW
              $this->image->rotateimage("#FFF", -90);
           break;

       }

 }

答案 1

“但是 - iMagick,当__construct此图像时,根据[方向] = >6(我认为!)自动将其旋转90度CCW。

问题实际上恰恰相反。Imagick不会自动旋转图像。您只能在其他软件/您的Web浏览器中正确看到它,因为这些程序会根据EXIF信息自动旋转它。Imagick 中的某些操作会导致您丢失正确的 EXIF 信息(复制图像、缩略图Image()、stripImage()和其他操作)。因此,在这种情况下,您需要做的实际上是物理旋转图像。

ajmicek的答案很好,但是通过使用Imagick自己的内置函数而不是PHP EXIF函数,可以对其进行一些改进。此外,该代码段似乎是类的一部分,因此它不能按原样用作单独的函数。在旋转后,使用 setImageOrientation() 设置正确的 EXIF 方向也是一个好主意。

// Note: $image is an Imagick object, not a filename! See example use below.
function autoRotateImage($image) {
    $orientation = $image->getImageOrientation();

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

        case imagick::ORIENTATION_RIGHTTOP:
            $image->rotateimage("#000", 90); // rotate 90 degrees CW
            break;

        case imagick::ORIENTATION_LEFTBOTTOM: 
            $image->rotateimage("#000", -90); // rotate 90 degrees CCW
            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);
}

使用示例:

$image = new Imagick('my-image-file.jpg');
autoRotateImage($image);
// - Do other stuff to the image here -
$image->writeImage('result-image.jpg');

推荐