ориентация изображения iOS имеет странное поведение
в течение последних нескольких недель я работал с изображениями в objective-c и заметил много странного поведения. Во-первых, как и у многих других людей, у меня была эта проблема, когда изображения, сделанные с помощью камеры (или сделанные с помощью чужой камеры и MMS-сообщений для меня), поворачиваются на 90 градусов. Я не был уверен, почему это происходит (отсюда и мой вопрос) но я смог придумать дешевые обойти.
мой вопрос на этот раз почему это происходит? Почему Apple вращает изображения? Когда я делаю снимок с моей камерой правой стороной вверх, если я не выполняю свой код, упомянутый выше,когда я сохраняю фотографию, она сохраняется повернутой. Теперь, мой обходной путь был в порядке до нескольких дней назад.
мое приложение изменяет отдельные пиксели изображения, в частности Альфа-канал PNG (поэтому любое преобразование 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 флаг. Я надеялся просто украсть этот код и использовать его, чтобы стереть мою ориентацию изображения, как только пользователь сделает снимок и добавит его в приложение, но он, похоже, не работает. Делает UIImageWriteToSavedPhotosAlbum сделать что-то особенное с imageOrientation?
было бы лучшим решением этой проблемы, чтобы просто сдуть imageOrientation Как только пользователь сделает снимок. Я предполагаю, что Apple имеет поведение вращения сделано по какой-то причине, не так ли? Несколько человек предположили, что это дефект Яблока.
(... если ты еще не потерял... Note2: когда я делаю горизонтальную фотографию, все, кажется, работает отлично, так же, как фотографии, сделанные из интернета)
EDIT:
вот что некоторые из изображения и сценарии на самом деле выглядят так. Основываясь на комментариях до сих пор, похоже, что это странное поведение-это больше, чем просто поведение iPhone, которое я думаю, хорошо.
это фотография фотографии, которую я взял с моего телефона (обратите внимание на правильную ориентацию), она выглядит точно так же, как и на моем телефоне, когда я щелкнул фотографию:

вот как выглядит изображение в Gmail после того, как я отправил его себе по электронной почте (похоже, Gmail обрабатывает его правильно):

вот как выглядит изображение в виде миниатюры в windows (не похоже, что оно обрабатывается должным образом):

и вот как выглядит фактическое изображение при открытии с помощью Windows Photo Viewer (все еще не обработано должным образом):

после всех комментариев по этому вопросу, вот что я думаю... IPhone берет изображение и говорит: "чтобы отобразить это правильно, его нужно повернуть на 90 градусов". Эта информация будет содержаться в данных EXIF. (Почему он должен быть повернут на 90 градусов, а не по умолчанию к прямой вертикали, я не знаю). Отсюда Gmail достаточно умен, чтобы читать и анализировать эти данные EXIF и правильно отображать их. Однако Windows недостаточно умна для чтения данных EXIF и поэтому отображает изображение неправильно. Верны ли мои предположения?
12 ответов:
Я сделал R & D на нем и обнаружил , что каждый файл изображения имеет свойство метаданных. Если метаданные определяют ориентацию изображения, которое обычно игнорируется другой ОС, но Mac. Большинство сделанных изображений имеют свойство метаданных, установленное под прямым углом. Таким образом, Mac показывает его на 90 градусов повернутым образом. Вы можете увидеть то же самое изображение в правильном направлении в ОС windows.
для более подробной информации прочитайте этот ответ http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm
попробуйте прочитать exif вашего изображения здесь 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/
У меня была такая же проблема, когда я получаю изображение с камеры, я поставил следующий код, чтобы исправить это.. Добавлен метод scaleAndRotateImage отсюда
- (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; }
быстрое копирование / вставка быстрый перевод Дилипа отличный ответ.
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; }
Swift 3 версия с проверками безопасности ответ Дилипа.
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 }
любое изображение, сгенерированное iPhone / iPad, сохраняется как пейзаж слева с тегом ориентации EXIF (Exif.Изображение.Ориентация) указание фактической ориентации.
Он имеет следующие значения: 1 : Пейзаж Слева 6 : Портрет Нормальный 3 : Пейзаж Справа 4 : Портрет Вверх Ногами
в IOS информация EXIF правильно считывается, и изображения отображаются таким же образом, как и было принято. Но в Windows информация EXIF не используется.
Если вы откроете одно из этих изображений в GIMP, он скажет, что изображение имеет информацию о вращении.
мой вопрос в этот раз, почему это происходит? Почему Apple вращает изображения?
ответ на этот вопрос очень прост. Apple не вращает изображение. Вот где кроется путаница.
ПЗС-камера не вращается, поэтому она всегда делает снимок в ландшафтном режиме.
Apple сделала очень умную вещь-вместо того, чтобы тратить все время на поворот изображения-перетасовка мегабайт данных вокруг - просто пометьте его тем, как изображение взятый.
OpenGL делает переводы очень легко-так что данные никогда не перетасовываются-просто как его рисуют.
отсюда и ориентация метаданных.
это становится проблемой, если вы хотите обрезать, изменить размер и т. д. - Но как только вы знаете, что происходит, вы просто определяете свою матрицу, и все работает.
для всех, кто использует Xamarin, вот перевод C# Дилипа отличный ответ!--3-->, и спасибо thattyson за Свифт перевод.
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; }
я столкнулся с этим вопросом, потому что у меня была аналогичная проблема, но с использованием Swift. Просто хотел сослаться на ответ, который работал для меня для любых других разработчиков Swift:https://stackoverflow.com/a/26676578/3904581
вот быстрый фрагмент кода, который эффективно устраняет проблему:
let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!супер просто. Одна строка кода. Проблема решена.
Я точно знаю, в чем твоя проблема. Вы используете UIImagePicker, что странно, во всех смыслах. Я бы предложил вам использовать AVFoundation для камеры, которая дает гибкость в ориентации, а также качество. Использовать AVCaptureSession. Вы можете получить код здесь Как сохранить фотографии, сделанные с помощью AVFoundation в фотоальбом?
быстро рефакторинг для 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! }
вот 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!; }
Comments