在过去的几周里,我一直在使用objective-c中的图像并注意到许多奇怪的行为。首先,像许多其他人一样,我一直遇到这个问题,用相机拍摄的图像(或用别人的相机和MMS给我拍摄)旋转90度。我不确定为什么在世界上这种情况发生了(因此my question)但我能够提出一个廉价的工作。
这次我的问题是为什么会发生这种情况?为什么Apple会旋转图像?当我用相机正面拍摄照片时,除非我执行上面提到的代码,否则当我保存照片时,它会被保存为旋转状态。现在,我的解决方法在几天前还可以。
我的应用程序修改了图像的各个像素,特别是PNG的alpha通道(因此任何JPEG转换都会从我的场景中抛出窗口)。几天前,我注意到即使图像在我的应用程序中正确显示,这要归功于我的解决方法代码,当我的算法修改图像的各个像素时,它认为图像是旋转的。因此,它不是修改图像顶部的像素,而是修改图像一侧的像素(因为它认为它应该被旋转)!我无法弄清楚如何在内存中旋转图像 - 理想情况下,我更愿意将imageOrientation
标记一起擦除。
以下是其他令我困惑的事情......当我拍摄照片时,imageOrientation
设置为3.我的解决方法代码非常智能,可以实现这一点并将其翻转,以便用户不会注意到。此外,我将图像保存到库中的代码实现了这一点,将其翻转,然后保存它以使其正确显示在相机胶卷中。
该代码如下:
NSData* pngdata = UIImagePNGRepresentation (self.workingImage); //PNG wrap
UIImage* img = [self rotateImageAppropriately:[UIImage imageWithData:pngdata]];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
当我将这个新保存的图像加载到我的应用程序中时,imageOrientation
为0 - 正是我想要看到的,我的旋转解决方法甚至不需要运行(注意:从互联网上加载图像时与使用相机拍摄的图像相反,imageOrientation
始终为0,从而产生完美的行为。出于某种原因,我的保存代码似乎擦掉了这个imageOrientation
标志。我希望只是窃取该代码,并在用户拍摄照片后将其用于擦除我的imageOrientation并将其添加到应用程序中,但它似乎无法正常工作。 UIImageWriteToSavedPhotosAlbum
imageOrientation
做了哪些特别的事情?
对于这个问题,最好的解决办法就是在用户完成拍摄图像后立即吹掉imageOrientation
。我认为Apple出于某种原因完成了旋转行为,对吧?一些人认为这是Apple的缺陷。
(...如果你还没有迷路......注2:当我拍摄水平照片时,一切似乎都很完美,就像从互联网上拍摄的照片一样)
编辑:
以下是一些图像和场景的实际情况。根据目前为止的评论,看起来这种奇怪的行为不仅仅是一种iPhone行为,我认为这很好。
这张照片是我用手机拍摄的照片(请注意正确的方向),它与拍摄照片时的手机完全一样:
以下是我通过电子邮件将图片发送给自己后的图片(看起来像Gmail正确处理):
以下是图片在Windows中作为缩略图的样子(看起来看起来没有正确处理):
以下是使用Windows Photo Viewer打开时的实际图像(仍未正确处理):
在对这个问题的所有评论之后,这就是我在想的...... iPhone拍摄了一张图像,并说“要正确显示,需要旋转90度”。此信息将在EXIF数据中。 (为什么它需要旋转90度,而不是默认直线垂直,我不知道)。从这里开始,Gmail非常智能,可以读取和分析EXIF数据,并正确显示它。但是,Windows不够智能,无法读取EXIF数据,因此显示图像不正确。我的假设是否正确?
答案 0 :(得分:54)
当我从Camera获取图像时遇到了同样的问题,我将以下代码修复它。添加了方法scaleAndRotateImage from here
- (void) imagePickerController:(UIImagePickerController *)thePicker didFinishPickingMediaWithInfo:(NSDictionary *)imageInfo {
// Images from the camera are always in landscape, so rotate
UIImage *image = [self scaleAndRotateImage: [imageInfo objectForKey:UIImagePickerControllerOriginalImage]];
//then save the image to photo gallery or wherever
}
- (UIImage *)scaleAndRotateImage:(UIImage *) image {
int kMaxResolution = 320;
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 = bounds.size.width / ratio;
}
else {
bounds.size.height = kMaxResolution;
bounds.size.width = 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;
}
答案 1 :(得分:47)
我在其上做了R& D并发现,每个图像文件都有元数据属性。如果元数据指定图像的方向,除了Mac之外,其他操作系统通常会忽略该方向。拍摄的大多数图像都将其元数据属性设置为直角。所以Mac显示它旋转90度的方式。您可以在Windows操作系统中以适当的方式查看相同的图像。
有关详细信息,请阅读此回答http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm
尝试在http://www.exifviewer.org/或http://regex.info/exif.cgi或http://www.addictivetips.com/internet-tips/view-complete-exif-metadata-information-of-any-jpeg-image-online/
中阅读您的图片。答案 2 :(得分:18)
快速复制/粘贴Dilip excellent answer的快速翻译。
import Darwin
class func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
let imgRef = imageSource.CGImage;
let width = CGFloat(CGImageGetWidth(imgRef));
let height = CGFloat(CGImageGetHeight(imgRef));
var bounds = CGRectMake(0, 0, width, height)
var scaleRatio : CGFloat = 1
if (width > maxResolution || height > maxResolution) {
scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
bounds.size.height = bounds.size.height * scaleRatio
bounds.size.width = bounds.size.width * scaleRatio
}
var transform = CGAffineTransformIdentity
let orient = imageSource.imageOrientation
let imageSize = CGSizeMake(CGFloat(CGImageGetWidth(imgRef)), CGFloat(CGImageGetHeight(imgRef)))
switch(imageSource.imageOrientation) {
case .Up :
transform = CGAffineTransformIdentity
case .UpMirrored :
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
case .Down :
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, CGFloat(M_PI));
case .DownMirrored :
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
case .Left :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * CGFloat(M_PI) / 2.0);
case .LeftMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * CGFloat(M_PI) / 2.0);
case .Right :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, CGFloat(M_PI) / 2.0);
case .RightMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, CGFloat(M_PI) / 2.0);
default : ()
}
UIGraphicsBeginImageContext(bounds.size)
let context = UIGraphicsGetCurrentContext()
if orient == .Right || orient == .Left {
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);
let imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;
}
答案 3 :(得分:13)
Swift 4版本,安全检查Dilip's answer。
public static func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat = 320) -> UIImage? {
guard let imgRef = imageSource.cgImage else {
return nil
}
let width = CGFloat(imgRef.width)
let height = CGFloat(imgRef.height)
var bounds = CGRect(x: 0, y: 0, width: width, height: height)
var scaleRatio : CGFloat = 1
if (width > maxResolution || height > maxResolution) {
scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
bounds.size.height = bounds.size.height * scaleRatio
bounds.size.width = bounds.size.width * scaleRatio
}
var transform = CGAffineTransform.identity
let orient = imageSource.imageOrientation
let imageSize = CGSize(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))
switch(imageSource.imageOrientation) {
case .up:
transform = .identity
case .upMirrored:
transform = CGAffineTransform
.init(translationX: imageSize.width, y: 0)
.scaledBy(x: -1.0, y: 1.0)
case .down:
transform = CGAffineTransform
.init(translationX: imageSize.width, y: imageSize.height)
.rotated(by: CGFloat.pi)
case .downMirrored:
transform = CGAffineTransform
.init(translationX: 0, y: imageSize.height)
.scaledBy(x: 1.0, y: -1.0)
case .left:
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform
.init(translationX: 0, y: imageSize.width)
.rotated(by: 3.0 * CGFloat.pi / 2.0)
case .leftMirrored:
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform
.init(translationX: imageSize.height, y: imageSize.width)
.scaledBy(x: -1.0, y: 1.0)
.rotated(by: 3.0 * CGFloat.pi / 2.0)
case .right :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform
.init(translationX: imageSize.height, y: 0)
.rotated(by: CGFloat.pi / 2.0)
case .rightMirrored:
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform
.init(scaleX: -1.0, y: 1.0)
.rotated(by: CGFloat.pi / 2.0)
}
UIGraphicsBeginImageContext(bounds.size)
if let context = UIGraphicsGetCurrentContext() {
if orient == .right || orient == .left {
context.scaleBy(x: -scaleRatio, y: scaleRatio)
context.translateBy(x: -height, y: 0)
} else {
context.scaleBy(x: scaleRatio, y: -scaleRatio)
context.translateBy(x: 0, y: -height)
}
context.concatenate(transform)
context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))
}
let imageCopy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return imageCopy
}
答案 4 :(得分:12)
iPhone / iPad生成的任何图像都保存为Landscape Left,并带有EXIF Orientation标记(Exif.Image.Orientation),指定实际方向。
它具有以下值: 1:左侧风景 6:人像正常 3:风景正确 4:人像颠倒
在IOS中,正确读取EXIF信息并以与拍摄时相同的方式显示图像。但在Windows中,不使用EXIF信息。
如果您在GIMP中打开其中一个图像,则表示该图像具有旋转信息。
答案 5 :(得分:11)
这次我的问题是为什么会发生这种情况?为什么Apple会旋转图像?
答案很简单。 Apple不会旋转图像。这就是混乱所在。
CCD相机无法旋转,因此它始终以横向模式拍摄照片。
Apple做了一件非常聪明的事情 - 而不是花费所有时间来旋转图像 - 将兆字节的数据混乱 - 只需用照片拍摄它来标记它。
OpenGL非常容易进行翻译 - 所以DATA永远不会被洗牌 - 只是它如何绘制。
因此取向元数据。
如果你想要裁剪,调整大小等,这就成了一个问题 - 但是一旦你知道发生了什么,你就可以定义你的矩阵,一切都会成功。
答案 6 :(得分:8)
对于任何使用Xamarin的人来说,这里是Dilip great answer的C#翻译,感谢Swift translation的那个。
public static UIImage RotateCameraImageToProperOrientation(UIImage imageSource, nfloat maxResolution) {
var imgRef = imageSource.CGImage;
var width = (nfloat)imgRef.Width;
var height = (nfloat)imgRef.Height;
var bounds = new CGRect(0, 0, width, height);
nfloat scaleRatio = 1;
if (width > maxResolution || height > maxResolution)
{
scaleRatio = (nfloat)Math.Min(maxResolution / bounds.Width, maxResolution / bounds.Height);
bounds.Height = bounds.Height * scaleRatio;
bounds.Width = bounds.Width * scaleRatio;
}
var transform = CGAffineTransform.MakeIdentity();
var orient = imageSource.Orientation;
var imageSize = new CGSize(imgRef.Width, imgRef.Height);
nfloat storedHeight;
switch(imageSource.Orientation) {
case UIImageOrientation.Up:
transform = CGAffineTransform.MakeIdentity();
break;
case UIImageOrientation.UpMirrored :
transform = CGAffineTransform.MakeTranslation(imageSize.Width, 0.0f);
transform = CGAffineTransform.Scale(transform, -1.0f, 1.0f);
break;
case UIImageOrientation.Down :
transform = CGAffineTransform.MakeTranslation(imageSize.Width, imageSize.Height);
transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI);
break;
case UIImageOrientation.DownMirrored :
transform = CGAffineTransform.MakeTranslation(0.0f, imageSize.Height);
transform = CGAffineTransform.Scale(transform, 1.0f, -1.0f);
break;
case UIImageOrientation.Left:
storedHeight = bounds.Height;
bounds.Height = bounds.Width;
bounds.Width = storedHeight;
transform = CGAffineTransform.MakeTranslation(0.0f, imageSize.Width);
transform = CGAffineTransform.Rotate(transform, 3.0f * (nfloat)Math.PI / 2.0f);
break;
case UIImageOrientation.LeftMirrored :
storedHeight = bounds.Height;
bounds.Height = bounds.Width;
bounds.Width = storedHeight;
transform = CGAffineTransform.MakeTranslation(imageSize.Height, imageSize.Width);
transform = CGAffineTransform.Scale(transform, -1.0f, 1.0f);
transform = CGAffineTransform.Rotate(transform, 3.0f * (nfloat)Math.PI / 2.0f);
break;
case UIImageOrientation.Right :
storedHeight = bounds.Height;
bounds.Height = bounds.Width;
bounds.Width = storedHeight;
transform = CGAffineTransform.MakeTranslation(imageSize.Height, 0.0f);
transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI / 2.0f);
break;
case UIImageOrientation.RightMirrored :
storedHeight = bounds.Height;
bounds.Height = bounds.Width;
bounds.Width = storedHeight;
transform = CGAffineTransform.MakeScale(-1.0f, 1.0f);
transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI / 2.0f);
break;
default :
break;
}
UIGraphics.BeginImageContext(bounds.Size);
var context = UIGraphics.GetCurrentContext();
if (orient == UIImageOrientation.Right || orient == UIImageOrientation.Left) {
context.ScaleCTM(-scaleRatio, scaleRatio);
context.TranslateCTM(-height, 0);
} else {
context.ScaleCTM(scaleRatio, -scaleRatio);
context.TranslateCTM(0, -height);
}
context.ConcatCTM(transform);
context.DrawImage(new CGRect(0, 0, width, height), imgRef);
var imageCopy = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return imageCopy;
}
答案 7 :(得分:3)
我遇到了这个问题,因为我遇到了类似的问题,但是使用了Swift。只是想链接到适用于任何其他Swift开发人员的答案:https://stackoverflow.com/a/26676578/3904581
这是一个可以有效解决问题的Swift代码段:
let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!
超级简单。一行代码。问题解决了。
答案 8 :(得分:0)
我确切地知道你的问题是什么。你正在使用UIImagePicker,这在任何意义上都很奇怪。我建议你使用AVFoundation作为相机,它提供了方向和质量的灵活性。使用AVCaptureSession。 您可以在此处获取代码How to save photos taken using AVFoundation to Photo Album?
答案 9 :(得分:0)
快速重构Swift 3(有人可以测试它并确认一切正常吗?):
static func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
let imgRef = imageSource.cgImage
let width = CGFloat(imgRef!.width)
let height = CGFloat(imgRef!.height)
var bounds = CGRect(x: 0, y: 0, width: width, height: height)
var scaleRatio : CGFloat = 1
if width > maxResolution || height > maxResolution {
scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
bounds.size.height = bounds.size.height * scaleRatio
bounds.size.width = bounds.size.width * scaleRatio
}
var transform = CGAffineTransform.identity
let orient = imageSource.imageOrientation
let imageSize = CGSize(width: imgRef!.width, height: imgRef!.height)
switch imageSource.imageOrientation {
case .up :
transform = CGAffineTransform.identity
case .upMirrored :
transform = CGAffineTransform(translationX: imageSize.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .down :
transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height)
transform = transform.rotated(by: CGFloat.pi)
case .downMirrored :
transform = CGAffineTransform(translationX: 0, y: imageSize.height)
transform = transform.scaledBy(x: 1, y: -1)
case .left :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: 0, y: imageSize.width)
transform = transform.rotated(by: 3.0 * CGFloat.pi / 2.0)
case .leftMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width)
transform = transform.scaledBy(x: -1, y: 1)
transform = transform.rotated(by: 3.0 * CGFloat.pi / 2.0)
case .right :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: imageSize.height, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2.0)
case .rightMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(scaleX: -1, y: 1)
transform = transform.rotated(by: CGFloat.pi / 2.0)
}
UIGraphicsBeginImageContext(bounds.size)
let context = UIGraphicsGetCurrentContext()
if orient == .right || orient == .left {
context!.scaleBy(x: -scaleRatio, y: scaleRatio)
context!.translateBy(x: -height, y: 0)
} else {
context!.scaleBy(x: scaleRatio, y: -scaleRatio)
context!.translateBy(x: 0, y: -height)
}
context!.concatenate(transform)
context!.draw(imgRef!, in: CGRect(x: 0, y: 0, width: width, height: height))
let imageCopy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return imageCopy!
}
答案 10 :(得分:0)
这是Dilip的Swift3版本的精彩答案
func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
let imgRef = imageSource.cgImage!;
let width = CGFloat(imgRef.width);
let height = CGFloat(imgRef.height);
var bounds = CGRect(x: 0, y: 0, width: width, height: height)
var scaleRatio : CGFloat = 1
if (width > maxResolution || height > maxResolution) {
scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
bounds.size.height = bounds.size.height * scaleRatio
bounds.size.width = bounds.size.width * scaleRatio
}
var transform = CGAffineTransform.identity
let orient = imageSource.imageOrientation
let imageSize = CGSize(width: width, height: height)
switch(imageSource.imageOrientation) {
case .up :
transform = CGAffineTransform.identity
case .upMirrored :
transform = CGAffineTransform(translationX: imageSize.width, y: 0.0);
transform = transform.scaledBy(x: -1, y: 1);
case .down :
transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height);
transform = transform.rotated(by: CGFloat(Double.pi));
case .downMirrored :
transform = CGAffineTransform(translationX: 0.0, y: imageSize.height);
transform = transform.scaledBy(x: 1, y: -1);
case .left :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform(translationX: 0.0, y: imageSize.width);
transform = transform.rotated(by: 3.0 * CGFloat(Double.pi) / 2.0);
case .leftMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width);
transform = transform.scaledBy(x: -1, y: 1);
transform = transform.rotated(by: 3.0 * CGFloat(Double.pi) / 2.0);
case .right :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform(translationX: imageSize.height, y: 0.0);
transform = transform.rotated(by: CGFloat(Double.pi) / 2.0);
case .rightMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width;
bounds.size.width = storedHeight;
transform = CGAffineTransform(scaleX: -1.0, y: 1.0);
transform = transform.rotated(by: CGFloat(Double.pi) / 2.0);
}
UIGraphicsBeginImageContext(bounds.size)
let context = UIGraphicsGetCurrentContext()!
if orient == .right || orient == .left {
context.scaleBy(x: -scaleRatio, y: scaleRatio);
context.translateBy(x: -height, y: 0);
} else {
context.scaleBy(x: scaleRatio, y: -scaleRatio);
context.translateBy(x: 0, y: -height);
}
context.concatenate(transform);
context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))
let imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy!;
}
答案 11 :(得分:0)
您可以通过此代码修复此 HECI 旋转图像
Swift 5 扩展:
extension UIImage {
/// Fix image orientaton to protrait up
func fixedOrientation() -> UIImage? {
guard imageOrientation != UIImage.Orientation.up else {
// This is default orientation, don't need to do anything
return self.copy() as? UIImage
}
guard let cgImage = self.cgImage else {
// CGImage is not available
return nil
}
guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
return nil // Not able to create CGContext
}
var transform: CGAffineTransform = CGAffineTransform.identity
switch imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: CGFloat.pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2.0)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: CGFloat.pi / -2.0)
case .up, .upMirrored:
break
@unknown default:
fatalError("Missing...")
break
}
// Flip image one more time if needed to, this is to prevent flipped image
switch imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
@unknown default:
fatalError("Missing...")
break
}
ctx.concatenate(transform)
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
default:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
break
}
guard let newCGImage = ctx.makeImage() else { return nil }
return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
}
}
目标 C 代码:
-(UIImage *)scaleAndRotateImage:(UIImage *)image{
// No-op if the orientation is already correct
if (image.imageOrientation == UIImageOrientationUp) return image;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
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;
}
代码的使用
UIImage *img=[info objectForKey:UIImagePickerControllerOriginalImage];
img=[self scaleAndRotateImage:img];
NSData *image = UIImageJPEGRepresentation(img, 0.1);
答案 12 :(得分:-3)
尝试将图像格式更改为.jpeg。这对我有用