Ориентация изображения 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 есть поворот, сделанный по какой-то причине, не так ли? Несколько человек предположили, что это дефект Apple.
(... если вы еще не потерялись... Примечание2: Когда я снимаю горизонтальную фотографию, все работает отлично, точно так же, как фотографии, сделанные из Интернета)
EDIT:
Вот некоторые из изображений и сценариев на самом деле. Исходя из комментариев до сих пор, похоже, что это странное поведение - это не просто поведение iPhone, которое, я думаю, хорошо.
Это фотография фотографии, которую я взял с моим телефоном (обратите внимание на правильную ориентацию), она отображается точно так же, как на моем телефоне, когда я щелкнул фотографию:
![Actual Photo taken on iPhone]()
Вот как выглядит изображение в Gmail после того, как я отправил его по электронной почте самому себе (похоже, что Gmail обрабатывает его правильно):
![Photo as it appears in Gmail]()
Вот как выглядит изображение в виде миниатюры в окнах (похоже, что оно не обрабатывается должным образом):
![Windows Thumbnail]()
И вот как выглядит фактическое изображение при открытии с помощью Windows Photo Viewer (все еще не обрабатывается должным образом):
![Windows Photo Viewer Version]()
После всех комментариев по этому вопросу, вот что я думаю... iPhone берет изображение и говорит "чтобы правильно отобразить его, его нужно поворачивать на 90 градусов". Эта информация будет в данных EXIF. (Почему его нужно поворачивать на 90 градусов, а не по умолчанию вертикально, я не знаю). Отсюда Gmail достаточно умен, чтобы читать и анализировать данные EXIF и правильно отображать их. Однако Windows недостаточно интеллектуальна для чтения данных EXIF и поэтому отображает изображение неправильно. Правильны ли мои предположения?
Ответы
Ответ 1
Я сделал 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/
Ответ 2
У меня была такая же проблема, когда я получил изображение с камеры, я поместил следующий код, чтобы исправить это. Добавил метод 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;
}
Ответ 3
Быстрая копия/вставка Быстрый перевод Dilip отличный ответ.
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;
}
Ответ 4
Версия Swift 4 с проверкой безопасности ответа Дилипа.
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
}
Ответ 5
Любое изображение, созданное iPhone/iPad, сохраняется как альбомная слева с тегом ориентации EXIF (Exif.Image.Orientation), определяющим фактическую ориентацию.
Он имеет следующие значения:
1: Пейзаж слева
6: Портрет Обычный
3: Пейзаж справа
4: Портрет вверх дном
В IOS информация EXIF считывается правильно, и изображения отображаются так же, как и в случае с ним. Но в Windows информация EXIF не используется.
Если вы откроете одно из этих изображений в GIMP, оно скажет, что изображение имеет информацию о ротации.
Ответ 6
Мой вопрос на этот раз, почему это происходит? Почему Apple поворачивает изображения?
Ответ на этот вопрос очень прост. Apple не поворачивает изображение. То, где лежит путаница.
ПЗС-камера не вращается, поэтому она всегда фотографирует в ландшафтном режиме.
Apple сделала очень умную вещь - вместо того, чтобы тратить все время на поворот изображения - перетасовывая мегабайты данных - просто пометьте его КАК, как было сделано изображение.
OpenGL делает переводы очень легко - поэтому DATA никогда не перетасовывается - просто КАК ЕГО ДРАЙН.
Следовательно, метаданные ориентации.
Это становится проблемой, если вы хотите обрезать, изменять размер и т.д. - но как только вы знаете, что происходит, вы просто определяете свою матрицу, и все работает.
Ответ 7
Для всех, кто использует Xamarin, здесь С# перевод Dilip отличный ответ, и спасибо thattyson для Swift перевод.
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;
}
Ответ 8
Я столкнулся с этим вопросом, потому что у меня была аналогичная проблема, но с использованием Swift. Просто хотел связать ответ, который работал у меня для любых других разработчиков Swift: fooobar.com/questions/73542/...
Вот фрагмент Swift, который эффективно устраняет проблему:
let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!
Супер простой. Одна строка кода. Проблема решена.
Ответ 9
Я точно знаю, в чем проблема. Вы используете UIImagePicker, что странно во всех смыслах. Я предлагаю вам использовать AVFoundation для камеры, которая обеспечивает гибкость в ориентации, а также качество. Используйте AVCaptureSession.
Вы можете получить здесь код Как сохранить фотографии, сделанные с помощью AVFoundation в фотоальбом?
Ответ 10
Быстрое рефакторинг для 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!
}
Ответ 11
Вот 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!;
}
Ответ 12
Попробуйте изменить формат изображения на .jpeg. Это сработало для меня