26

目前正在使用 PHP 和 iMagick 开发海报打印 Web 应用程序。

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

替代文字

该图像包含以下 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

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

替代文字

我想知道的是...

如何保持页面顶部图像的原始方向?这是否可以通过禁用 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;

       }

 }
4

5 回答 5

58

“但是 - iMagick 使用此图像构建时,会根据 [方向] => 6 自动将其逆时针旋转 90 度(我认为!)。”

问题实际上与此相反。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');
于 2013-02-20T21:04:24.937 回答
4

试试Imagick::setImageOrientation。试验可用的常数

于 2010-11-24T13:36:38.993 回答
2

良好的开端——添加一些使函数更健壮的内容。首先,第 3 种情况发生在图像上下颠倒时。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,但是哦,好吧。

哦,还有:旋转是有损操作(除非你使用 jpegtran),所以你应该尝试只结合调整大小或其他转换来做。

于 2012-01-20T17:36:10.123 回答
0

orrd的优秀答案中的这段代码需要iMagick 6.3+版本。:

$image->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>";
于 2014-05-31T05:42:05.897 回答
0
function thumbnailImage($imagePath,$color,$quality)
{   

    $fileType = pathinfo($imagePath, PATHINFO_EXTENSION);

    if (!empty($fileType))
    {
        switch($fileType)
        {
            case "gif":
                $im = imagecreatefromgif($imagePath);
                break;

            case "jpg":
                $im = imagecreatefromjpeg($imagePath);
                break;

            case "jpeg":
                $im = imagecreatefromjpeg($imagePath);
                break;

            case "png":
                $im = imagecreatefrompng($imagePath);
                break;
        }
    }

    $imagick = new Imagick();
    $imagick->readImage($imagePath);
    $compression_type = Imagick::COMPRESSION_JPEG; 
    $imagick->setImageCompression($compression_type);
    $imagick->setImageCompressionQuality($quality);

    if ($fileType == "jpeg" || $fileType == "jpeg" )
    {
        $exif = exif_read_data($imagePath);
        if (!empty($exif['Orientation'])) {
            switch ($exif['Orientation']) {
                case 3:
                    $imagick = imagerotate($imagick, 180, 0);
                    break;

                case 6:
                    $imagick = imagerotate($imagick, -90, 0);
                    break;

                case 8:
                    $imagick = imagerotate($imagick, 90, 0);
                    break;
            }
        }
    }
    $imagick->setImageBackgroundColor($color);
    $imagick->thumbnailImage(150, 150, true, true);
    header("Content-type: image/jpg");
    echo $imagick->getImageBlob();
}

超级简单的缩略图。打电话给

thumbnailImage('file.ext','#ffffff',50); // full path, color, quality 1-100

适用于jpggifpng显然只适用EXIF于 jpeg

缩略图将加载到页面上,如果您指定您的,您可以通过 URL 调用它$_GETs

请享用

于 2020-01-16T16:56:09.310 回答