上传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图片方向的主要内容,如果未能解决你的问题,请参考以下文章