2010-11-24 98 views
18

目前正在使用PHP和iMagick开发海报打印Web应用程序。如何停止基于EXIF'orientation'数据的PHP iMagick自动旋转图像

这是我使用来测试应用程序的上载/图像编辑功能的图象例子:

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 ,当用这个图像构建__结构时,根据[Orientation] => 6(我想!)自动将其旋转90度CCW。造成这种...

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; 

     } 

} 

回答

3
+0

thanks izym。你有关于如何使用这些常量的更多信息? – kaese 2010-11-24 14:24:05

+1

请注意,Imagick :: setImageOrientation()实际上并不旋转图像,它只是更改将与图像一起保存的EXIF旋转信息。在某些情况下,可能是您想要做的事情,但通常最好是实际旋转图像(请参阅我发布的代码示例作为答案)。依靠EXIF旋转信息的问题是,并非所有的Web浏览器和图像查看软件都会自动将其正确定向。 – orrd 2013-02-20 21:07:40

1

良好的开端 - 一些补充,使功能更强大。首先,当图像颠倒时出现情况3。有一个伟大的说明不同的方向代码by Calvin Hass。 方位信息可能出现在exif_read_data阵列的不同位置(取决于相机型号,我认为),所以我试图在我的示例代码中考虑到这一点。

事情是这样的:

public function fixOrientation() { 

    $exif = exif_read_data($this->imgSrc); 

    if(isset($exif['Orientation'])) 
     $orientation = $exif['Orientation']; 
    elseif(isset($exif['IFD0']['Orientation'])) 
     $orientation = $exif['IFD0']['Orientation']; 
    else 
     return false; 

    switch($orientation) { 
     case 3: // rotate 180 degrees 
      $this->image->rotateimage("#FFF", 180); 
     break; 

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

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

改造&节省离开你没有以前的EXIF信息,包括Orientation。经转换的图像中的缺少Orientation将防止进一步的处理尝试通过再次旋转来“纠正”事物。我希望Imagick支持ImageMagick's -auto-orient,但哦。

另外:旋转是一个lossy operation(除非您使用jpegtran),所以您应该尝试仅与调整大小或其他转换结合使用。

+0

原有功能的新增功能 - 谢谢! – kaese 2012-03-13 11:36:21

39

“但是 - iMagick,当用这个图像__构造时,按照[方向] => 6(我想!),自动将它旋转90度CCW。

问题其实是相反的。 Imagick 不会自动旋转图像。您只能在其他软件/浏览器中正确看到它,因为这些程序会根据EXIF信息自动旋转它。Imagick中的某些操作会导致您丢失正确的EXIF信息(复制图像,thumbnailImage(),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'); 
0

这段代码在orrd的出色答卷,需要iMagick版本6.3+:

$图像 - > setImageOrientation(imagick :: ORIENTATION_TOPLEFT);

完美地工作,并照顾操作系统/设备方向的差异。不适用于6.2。

我已编码获取设备。这里万一有人需要它。

$ua = $_SERVER['HTTP_USER_AGENT']; 
$strcut = stristr($ua, '(')."<br>"; 
$textlen = strpos($strcut,";"); 
$deviceos = substr($strcut,1,($textlen-1)); 
echo "Device O/S: * $deviceos"."<br>";