php 如何检测照片的拍摄角度,并像桌面应用程序在查看时一样自动旋转网站显示?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3657023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:35:17  来源:igfitidea点击:

How to detect shot angle of photo, and auto rotate for website display like desktop apps do on viewing?

phpimage-processing

提问by Pentium10

If I take a photo with a camera it stores the orientation/angle of the apparatus so when I view the image on the PC with a good app, it shows auto-rotated to 0.

如果我用相机拍照,它会存储设备的方向/角度,所以当我用一个好的应用程序在 PC 上查看图像时,它会显示自动旋转到 0。

But when I upload to a website it shows the original angle, so the image doesn't look good.

但是当我上传到网站时,它显示的是原始角度,所以图像看起来不太好。

How can I detect this with PHP and rotate the image, and clear this angle flag from it's meta information.

我怎样才能用 PHP 检测到这一点并旋转图像,并从它的元信息中清除这个角度标志。

回答by Andrew Moore

In order to do that, you must read the EXIF information out of the JPEG file. You can either do that with exifPHP extension or with PEL.

为此,您必须从 JPEG 文件中读取 EXIF 信息。您可以使用exifPHP 扩展或PEL.

Basically, you have to read the Orientationflag in the file. Here is an example using the exifPHP extension and WideImagefor image manipulation.

基本上,您必须读取Orientation文件中的标志。这是一个使用exifPHP 扩展和WideImage图像处理的示例。

<?php
$exif = exif_read_data($filename);
$ort = $exif['Orientation'];

$image = WideImage::load($filename);

// GD doesn't support EXIF, so all information is removed.
$image->exifOrient($ort)->saveToFile($filename);

class WideImage_Operation_ExifOrient
{
  /**
   * Rotates and mirrors and image properly based on current orientation value
   *
   * @param WideImage_Image $img
   * @param int $orientation
   * @return WideImage_Image
   */
  function execute($img, $orientation)
  {
    switch ($orientation) {
      case 2:
        return $img->mirror();
        break;

      case 3:
        return $img->rotate(180);
        break;

      case 4:
        return $img->rotate(180)->mirror();
        break;

      case 5:
        return $img->rotate(90)->mirror();
        break;

      case 6:
        return $img->rotate(90);
        break;

      case 7:
        return $img->rotate(-90)->mirror();
        break;

      case 8:
        return $img->rotate(-90);
        break;

      default: return $img->copy();
    }
  }
}

回答by Wes

I modified Chris' example to add a check for the exif function, remove the mirroring, and also to write the file back out to the filesystem using the same filename. This way, you can call this function right after calling move_uploaded_file, like this:

我修改了 Chris 的示例以添加对 exif 函数的检查,删除镜像,并使用相同的文件名将文件写回文件系统。这样,您可以在调用 move_uploaded_file 后立即调用此函数,如下所示:

move_uploaded_file($uploadedFile, $destinationFilename);
correctImageOrientation($destinationFilename);


function correctImageOrientation($filename) {
  if (function_exists('exif_read_data')) {
    $exif = exif_read_data($filename);
    if($exif && isset($exif['Orientation'])) {
      $orientation = $exif['Orientation'];
      if($orientation != 1){
        $img = imagecreatefromjpeg($filename);
        $deg = 0;
        switch ($orientation) {
          case 3:
            $deg = 180;
            break;
          case 6:
            $deg = 270;
            break;
          case 8:
            $deg = 90;
            break;
        }
        if ($deg) {
          $img = imagerotate($img, $deg, 0);        
        }
        // then rewrite the rotated image back to the disk as $filename 
        imagejpeg($img, $filename, 95);
      } // if there is some rotation necessary
    } // if have the exif orientation info
  } // if function exists      
}

回答by Chris Cinelli

If you just want to use GD and the php EXIF extension you can use this:

如果你只想使用 GD 和 php EXIF 扩展,你可以使用这个:

function _mirrorImage ( $imgsrc)
{
    $width = imagesx ( $imgsrc );
    $height = imagesy ( $imgsrc );

    $src_x = $width -1;
    $src_y = 0;
    $src_width = -$width;
    $src_height = $height;

    $imgdest = imagecreatetruecolor ( $width, $height );

    if ( imagecopyresampled ( $imgdest, $imgsrc, 0, 0, $src_x, $src_y, $width, $height, $src_width, $src_height ) )
    {
        return $imgdest;
    }

    return $imgsrc;
}

function adjustPicOrientation($full_filename){        
    $exif = exif_read_data($full_filename);
    if($exif && isset($exif['Orientation'])) {
        $orientation = $exif['Orientation'];
        if($orientation != 1){
            $img = imagecreatefromjpeg($full_filename);

            $mirror = false;
            $deg    = 0;

            switch ($orientation) {
              case 2:
                $mirror = true;
                break;
              case 3:
                $deg = 180;
                break;
              case 4:
                $deg = 180;
                $mirror = true;  
                break;
              case 5:
                $deg = 270;
                $mirror = true; 
                break;
              case 6:
                $deg = 270;
                break;
              case 7:
                $deg = 90;
                $mirror = true; 
                break;
              case 8:
                $deg = 90;
                break;
            }
            if ($deg) $img = imagerotate($img, $deg, 0); 
            if ($mirror) $img = _mirrorImage($img);
            $full_filename = str_replace('.jpg', "-O$orientation.jpg",  $full_filename); 
            imagejpeg($img, $full_filename, 95);
        }
    }
    return $full_filename;
}

回答by Chris Cinelli

The rotation flag is stored as part of the EXIF data (see this articlefor more info).

旋转标志存储为 EXIF 数据的一部分(有关更多信息,请参阅此文章)。

You will need to read the rotation flag from the EXIF data in PHP and then rotate the image to suit. There are a variety of PHP EXIF libraries, if you have the web server set up with the extension installed you would be able to use the PHP provided library.

您需要从 PHP 中的 EXIF 数据读取旋转标志,然后旋转图像以适应。有多种 PHP EXIF 库,如果您设置了 Web 服务器并安装了扩展,您将能够使用PHP 提供的库

I would suggest rotating the image once on upload (e.g. using the GD library- most PHP installations these days seem to come with it), so that you don't need to worry about clearing the EXIF rotation data (not sure how easy this is with PHP, I've never tried it).

我建议在上传时旋转一次图像(例如使用GD 库- 现在大多数 PHP 安装似乎都附带它),这样您就不必担心清除 EXIF 旋转数据(不确定这有多容易)使用 PHP,我从未尝试过)。