上传PHP后修复iOS图片方向

Posted

技术标签:

【中文标题】上传PHP后修复iOS图片方向【英文标题】:Fix iOS picture orientation after upload PHP 【发布时间】:2014-04-14 01:45:05 【问题描述】:

如果从 ios 上传后没有正确定位,有没有办法使用 php 旋转图片?

有些图片旋转了 90 度,而另一些则正确上传。

【问题讨论】:

这会帮助你***.com/questions/14231552/… IOS 设备在拍照时处理图像的方向。如果照片在上传到您的服务时未正确旋转,则设备在拍摄时无法正确判断方向,照片需要由人旋转。 您要么对无损 JPEG 旋转感兴趣(AFAIK 可能以 90 度为步长,您可以在此处找到库:sylvana.net/jpegcrop/jpegtran)和/或更改该图像的方向元数据字段。这取决于文件类型以及设备如何处理它(参见@Sammitch 写的内容)。 【参考方案1】:

使用 GD 库,我们可以在 PHP 中操作图像。该脚本使用 imagerotate() 函数来旋转照片。在我们的例子中,我们将其旋转 90 度,但这可以在脚本中进行更改。

 <?php 
 // The file you are rotating
 $image = 'myfile.jpg';

 //How many degrees you wish to rotate
 $degrees = 90;

 // This sets the image type to .jpg but can be changed to png or gif
 header('Content-type: image/jpeg') ;

 // Create the canvas
 $source = imagecreatefromjpeg($image) ;

 // Rotates the image
 $rotate = imagerotate($source, $degrees, 0) ;

 // Outputs a jpg image, you could change this to gif or png if needed
 imagejpeg($rotate) ;
 ?> 

这个脚本最重要的部分,旋转,是用 imagerotate() 函数完成的。这个函数的参数是:

imagerotate (The_image, degrees_to_rotate, background_color, Optional_ignore_transparency)

如果可选的忽略透明度为空白或 0,则保留透明度。

array getimagesize ( string $filename [, array &$imageinfo ] )

getimagesize() 函数将确定任何给定图像文件的大小,并返回尺寸以及文件类型和要在普通 html IMG 标记和相应 HTTP 内容类型中使用的高度/宽度文本字符串。

您应该使用它来检查手机图像的方向,以便知道何时调用 imagerotate()。

您还可以使用 imagejpeg 保存图像。 http://www.php.net/manual/en/function.imagejpeg.php

// Save the image as 'path/to/myfile.jpg'
imagejpeg($image, 'path/to/myfile.jpg');

// Free up memory
imagedestroy($image);

【讨论】:

【参考方案2】:
// File and rotation
$filename = 'test.jpg';
$degrees = 180;

// Content type
header('Content-type: image/jpeg');

// Load
$source = imagecreatefromjpeg($filename);

// Rotate
$rotate = imagerotate($source, $degrees, 0);

// Output
imagejpeg($rotate);

check this link :
http://www.php.net/manual/en/function.imagerotate.php

【讨论】:

【参考方案3】:

它并不能完全回答您的问题,但我总是使用此脚本来修复方向并缩放到预上传的合理尺寸。这样,您可以为应用程序用户节省一些带宽,并且无需在服务器端做任何事情。

- (UIImage *)scaleAndRotateImage:(UIImage *)image 
    int kMaxResolution = 1024; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);


    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) 
        CGFloat ratio = width/height;
        if (ratio > 1) 
            bounds.size.width = kMaxResolution;
            bounds.size.height = roundf(bounds.size.width / ratio);
        
        else 
            bounds.size.height = kMaxResolution;
            bounds.size.width = roundf(bounds.size.height * ratio);
        
    

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) 

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) 
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    
    else 
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
       CGContextTranslateCTM(context, 0, -height);
    

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;

【讨论】:

【参考方案4】:

图像正在旋转,因为您将图像保存为 JPEG,如果您将图像保存为 PNG,则方向不会改变。这是解决方向问题的代码。

- (UIImage *)fixrotation:(UIImage *)image   

    if (image.imageOrientation == UIImageOrientationUp) return image;
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (image.imageOrientation) 
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, image.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationUpMirrored:
            break;
    

    switch (image.imageOrientation) 
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationDown:
        case UIImageOrientationLeft:
        case UIImageOrientationRight:
            break;
    

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
                                             CGImageGetBitsPerComponent(image.CGImage), 0,
                                             CGImageGetColorSpace(image.CGImage),
                                             CGImageGetBitmapInfo(image.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (image.imageOrientation) 
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
            break;
    

    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;

【讨论】:

如何使用图像运行此代码?这像一个函数吗? 你需要调用这个函数,它会返回给你旋转的图像。 我怎么称呼它?我认为它与[self fixrotation]; 或其他东西不同。 UIImage *imageNew = [self fixrotation:yourOldImage];这样它调用的 感谢您的帮助,我一直收到此错误,当我调用函数*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMutableData imageOrientation]: unrecognized selector sent to instance 0x15f1d7a0'时它崩溃了【参考方案5】:

使用exif_read_data找出图像的方向:

$exif = exif_read_data('image.jpg');

if (isset($exif['Orientation']))

  switch ($exif['Orientation'])
  
    case 3:
      // Need to rotate 180 deg
      break;

    case 6:
      // Need to rotate 90 deg clockwise
      break;

    case 8:
      // Need to rotate 90 deg counter clockwise
      break;
  

您可以在此处找到有关方向代码的说明: http://www.impulseadventure.com/photo/exif-orientation.html

【讨论】:

不确定为什么选择了赏金答案;这似乎是一个与如何在通过 iOS 将图像上传到 PHP 脚本然后显示后如何操作图像有关的问题。我遇到过这个,这似乎是最好的答案。上面的答案给出了 iOS 的 Objective C 中的代码。 这个脚本似乎更有用。无论您从 iphone 上传非垂直照片的位置(您可以从笔记本电脑上传),自动旋转的过程都必须在终点:在网站或 API 中......您可以在哪里做很多对您的图片进行其他处理(调整大小、复制...)。对不起我丑陋的英语【参考方案6】:

我已经创建了一个功能来校正存档图像,您可以使用它稍作修改来进行直播校正。

gist link of the function

<?php
/*
Correct image orientation v1.0

Author: Mathuvathanan Mounasamy

Licensed under the MIT license

This function correct all the images' orientation in a given path or directory.

Run:    php -r "require 'correctImageOrientation.php'; correctImageOrientation('test/');"
        or
        php -r "require 'correctImageOrientation.php'; correctImageOrientation('test/test1');"
        or
        php -r "require 'correctImageOrientation.php'; correctImageOrientation('test');"
*/
function correctImageOrientation($directory) 
    $scanned_directory = array_diff(scandir($directory), array('..', '.'));
    echo "<pre>";
    print_r("scanned directory: \r\n");
    print_r($scanned_directory);
    echo "</pre>\r\n";
    foreach ($scanned_directory as &$file) 

        if (is_dir($directory."/".$file)) 
            correctImageOrientation($directory."/".$file);
         else                                     
            $filen = explode(".", $file);
            $ext = end($filen);
            try 

                $exif = @exif_read_data($directory."/".$file);

                $orientation = $exif['Orientation'];

                if (isset($orientation) && $orientation != 1)
                    switch ($orientation) 
                        case 3:
                        $deg = 180;
                        break;
                        case 6:
                        $deg = 270;
                        break;
                        case 8:
                        $deg = 90;
                        break;
                    

                    if ($deg) 

                        // If png
                        if ($ext == "png") 
                            $img_new = imagecreatefrompng($directory."/".$file);
                            $img_new = imagerotate($img_new, $deg, 0);

                            // Save rotated image
                            imagepng($img_new,$directory.$file);
                        else 
                            $img_new = imagecreatefromjpeg($directory."/".$file);
                            $img_new = imagerotate($img_new, $deg, 0);

                            // Save rotated image
                            imagejpeg($img_new,$directory."/".$file,80);
                        
                    
                    echo "<pre>";
                    print_r("image changed: \r\n");
                    print_r($directory."/".$file);
                    echo "</pre>\r\n";
                

             catch (Exception $e) 
                echo "error:";
                echo $e;
                echo "error";
            
        
    
    unset($file);


?>

【讨论】:

我为我编辑了刚刚更新的一个文件。很棒的代码!【参考方案7】:

如果您使用 ImageMagick,有一个非常简单的修复方法,只需将 -auto-orient 添加到您的命令即可。

convert -auto-orient -quality 90 -resize 1200x800 $f-new

【讨论】:

【参考方案8】:

您可以在文件夹中上传图片后添加以下脚本

 $filename = "/files/1.jpg"; /*ADD YOUR FILENAME WITH PATH*/
 $exif = exif_read_data($filename);
 $ort = $exif['Orientation']; /*STORES ORIENTATION FROM IMAGE */
 $ort1 = $ort;
 $exif = exif_read_data($filename, 0, true);
    if (!empty($ort1))
     
       $image = imagecreatefromjpeg($filename);
       $ort = $ort1;
          switch ($ort) 
                case 3:
                    $image = imagerotate($image, 180, 0);
                    break;

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

                case 8:
                    $image = imagerotate($image, 90, 0);
                    break;
            
        
       imagejpeg($image,$filename, 90); /*IF FOUND ORIENTATION THEN ROTATE IMAGE IN PERFECT DIMENSION*/

此脚本在图片上传到文件夹后生效,因此您可以在上传文件夹后添加此脚本

【讨论】:

以上是关于上传PHP后修复iOS图片方向的主要内容,如果未能解决你的问题,请参考以下文章

移动端web头像上传实现截取和照片方向修复

iOS方向更改缩放错误修复

如何修复 Axios 中的图片上传问题

上传图片时如何修复 WordPress 上的 HTTP 错误?

网站漏洞修复被 提示该网站内容被禁止访问

PHP 通过Windows修复代码点火器csv上传