2012-06-01 6 views
32

Я исследовал достаточно, чтобы получить эту работу, но не смог ее исправить. После съемки с камеры, пока у меня есть изображение, хранящееся как UIImage, это нормально, но как только я сохранил это изображение в качестве представления PNG, его можно поворачивать на 90 градусов.iOS: изображение поворачивается на 90 градусов после сохранения в виде данных представления PNG

Ниже мой код и все вещи, которые я пробовал:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType]; 

    if([mediaType isEqualToString:(NSString*)kUTTypeImage]) 
    { 
     AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
     delegate.originalPhoto = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; 
     NSLog(@"Saving photo"); 
     [self saveImage]; 
     NSLog(@"Fixing orientation"); 
     delegate.fixOrientationPhoto = [self fixOrientation:[UIImage imageWithContentsOfFile:[delegate filePath:imageName]]];  
     NSLog(@"Scaling photo"); 
     delegate.scaledAndRotatedPhoto = [self scaleAndRotateImage:[UIImage imageWithContentsOfFile:[delegate filePath:imageName]]]; 
    } 
    [picker dismissModalViewControllerAnimated:YES]; 
    [picker release]; 
} 


- (void)saveImage 
{ 
    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
    NSData *imageData = UIImagePNGRepresentation(delegate.originalPhoto); 
    [imageData writeToFile:[delegate filePath:imageName] atomically:YES]; 
} 

Здесь fixOrientation и scaleAndRotateImage функции взяты из here и here соответственно. Они отлично работают и поворачивают изображение, когда я применяю их в UIImage, но не работают, если я сохраняю изображение как представление PNG и применяю их.

Пожалуйста refere следующей картины после выполнения вышеуказанных функций:

The first photo is original, second is saved, and third and fourth after applying fixorientation and scaleandrotate functions on saved image

+0

1. [изображение щелкнул с iPhone в портретном режиме получает повернутой на 90 градусов] (HTTP://stackoverflow.com/questions/5973105/image-clicked-from-iphone-in-portrait-mode-gets-rotated-by-90-degree) 2. [Ориентация изображения на изображение камеры] (http: // stackoverflow .com/вопросы/4565507/camera-image-changes-orientation) –

+1

Nope buddy. Вы вставляете все ссылки относительно этой проблемы. Я прошел через все их! – applefreak

+1

Аноним, если вы отрицаете этот вопрос, тогда вы не поняли вопроса! Я мог видеть, что у вас есть эта проблема здесь - http://stackoverflow.com/questions/3554244/uiimagepngrepresentation-issues :-) Вы решили это? – applefreak

ответ

57

Начиная с прошивкой 4.0, когда камера делает снимок не вращать его перед сохранением, он

просто задает вращение флаг в EXIF-данных JPEG. Если вы сохраните UIImage в формате JPEG, то

установит флаг вращения. ПНГ не поддерживают флаг вращения, поэтому, если вы сохраните UIImage как

PNG, он будет повернут неправильно и не установлен флаг для его исправления. Поэтому, если вы хотите PNG

изображений, вы должны повернуть их самостоятельно, для этого установите флажок link.

+1

Вы были правы. Это заняло у меня по крайней мере 24 часа, чтобы исправить !!! – applefreak

+0

Я бы рекомендовал прочитать это [ответ.] (Http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-image-orientation-after-upload). В частности, ответ «an0» представляется наиболее кратким , –

+0

супер работая хорошо спасибо. – vijay

1

Pls Попробуйте следующий код

UIImage *sourceImage = ... // Our image 
CGRect selectionRect = CGRectMake(100.0, 100.0, 300.0, 400.0); 
CGImageRef resultImageRef = CGImageCreateWithImageInRect(sourceImage.CGImage, 
selectionRect); 
UIImage *resultImage = [[UIImage alloc] initWithCGImage:resultImageRef]; 

И

CGRect TransformCGRectForUIImageOrientation(CGRect source, UIImageOrientation orientation, CGSize imageSize) { 
switch (orientation) { 
case UIImageOrientationLeft: { // EXIF #8 
    CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.height, 0.0); 
    CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI_2); 
    return CGRectApplyAffineTransform(source, txCompound); 
} 
case UIImageOrientationDown: { // EXIF #3 
    CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); 
    CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI); 
    return CGRectApplyAffineTransform(source, txCompound); 
} 
case UIImageOrientationRight: { // EXIF #6 
    CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(0.0, imageSize.width); 
    CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI + M_PI_2); 
    return CGRectApplyAffineTransform(source, txCompound); 
} 
case UIImageOrientationUp: // EXIF #1 - do nothing 
    default: // EXIF 2,4,5,7 - ignore 
    return source; 
} 
} 
    ... 
UIImage *sourceImage = ... // Our image 
CGRect selectionRect = CGRectMake(100.0, 100.0, 300.0, 400.0); 
CGRect transformedRect = TransformCGRectForUIImageOrientation(selectionRect, sourceImage.imageOrientation, sourceImage.size); 
CGImageRef resultImageRef = CGImageCreateWithImageInRect(sourceImage.CGImage, transformedRect); 
UIImage *resultImage = [[UIImage alloc] initWithCGImage:resultImageRef]; 

Я referanced из следующей связи имеют вид для более detail

С наилучшими пожеланиями :-)

+0

Спасибо, но это тоже не сработало. Я использовал выбор CGRectRect = CGRectMake (0, 0, sourceImage.size.width, sourceImage.size.height); для поворота полного изображения, но все же оно появляется на 90 градусов. Обратите внимание, что я выполняю эту операцию после сохранения изображения локально в папке документов. Благодарю. – applefreak

+0

Откуда вы передаете значение «ориентация» в «CGRect TransformCGRectForUIImageOrientation (источник CGRect, ориентация UIImageOrientation, CGSize imageSize) – Developer

5

У меня есть нашел следующие советы, которые будут чрезвычайно полезны:

1. естественный выход является пейзаж

2. .width/.height страдают от .imageOrientation

3 использовать короткие измерения, а не .width


(1) «естественный» выход камеры для неподвижных изображений IS LANDSCAPE.

Это противоречиво. портрет - это единственный способ, предлагаемый UIImagePickerController и т. д. Но вы получите UIImageOrientationRight как «нормальную» ориентацию при использовании «нормальной» портретной камеры

(Как я помню это - естественный выход для видео (конечно) пейзаж, так что неподвижные изображения одинаковы - даже если iPhone - это портрет.)


(2) .width и .height действительно пострадали от .imageOrientation !!!!!!!!!

Будьте уверены, чтобы сделать это, и попробовать его в обоих направлениях на вашем iPhone,

NSLog(@"fromImage.imageOrientation is %d", fromImage.imageOrientation); 
NSLog(@"fromImage.size.width %f fromImage.size.height %f", 
      fromImage.size.width, fromImage.size.height); 

вы увидите, что .height и .width своп «хотя» реальные пиксели пейзаж.


(3) просто используя «короткое измерение», а не .width, часто может решить многие проблемы

я нашел, что это будет невероятно полезным. Допустим, вы хотите, возможно, верхний квадрат изображения:

CGRect topRectOfOriginal = CGRectMake(0,0, im.size.width,im.size.width); 

, что на самом деле не будет работать, вы получите сплющенные изображение, когда камера («на самом деле»), который держат пейзаж.

однако если вы очень просто сделать это

float shortDimension = fminf(im.size.width, im.size.height); 
CGRect topRectOfOriginal = CGRectMake(0,0, shortDimension,shortDimension); 

тогда «все фиксировано», и вы на самом деле «не нужно беспокоиться о» флаг ориентации. Опять же точка (3) не является лекарством, но очень часто решает все проблемы.

Надеюсь, что это поможет кому-то сэкономить время.

+0

Я полагаю, что в последнем примере вы должны использовать' shortDimension' где-нибудь (возможно, вместо 'im.size. width' во второй строке?) – furins

+0

спасибо @furins !! – Fattie

0

Попробуйте этот код:

NSData *imageData = UIImageJPEGRepresentation(delegate.originalPhoto,100); 
+0

Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий ниже своего сообщения - вы всегда можете прокомментировать свои собственные сообщения, и как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/whats-reputation), вы будете быть в состоянии [прокомментировать любое сообщение] (http://stackoverflow.com/help/privileges/comment). – ericbn

+1

Проблема с вращением возникает, когда вы храните изображение как PNGRпредставление. Если вы храните изображение в виде JPEGRepresentation, изображение не будет вращаться! – Mubasher

2

Я нашел этот код here, который на самом деле фиксированной это для меня. Для моего приложения я сделал снимок и сохранил его, и каждый раз, когда я его загружал, у него было бы раздражающее вращение (я посмотрел вверх, и это, по-видимому, что-то связано с EXIF ​​и тем, как iPhone берет и хранит изображения). Этот код исправил это для меня. Я должен сказать, что он был первоначально дополнением к классу/расширению/категории (вы можете найти оригинал по ссылке. Я использовал его как ниже, как простой метод, так как я действительно не хотел делать целое .. класс или категорию именно для этого я использовал только портрет, но я думаю, что код работает для любой ориентации я не уверен, хотя

Рант закончилась, вот код:

- (UIImage *)fixOrientationForImage:(UIImage*)neededImage { 

    // No-op if the orientation is already correct 
    if (neededImage.imageOrientation == UIImageOrientationUp) return neededImage; 

    // 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 (neededImage.imageOrientation) { 
     case UIImageOrientationDown: 
     case UIImageOrientationDownMirrored: 
      transform = CGAffineTransformTranslate(transform, neededImage.size.width, neededImage.size.height); 
      transform = CGAffineTransformRotate(transform, M_PI); 
      break; 

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

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

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

     case UIImageOrientationLeftMirrored: 
     case UIImageOrientationRightMirrored: 
      transform = CGAffineTransformTranslate(transform, neededImage.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, neededImage.size.width, neededImage.size.height, 
              CGImageGetBitsPerComponent(neededImage.CGImage), 0, 
              CGImageGetColorSpace(neededImage.CGImage), 
              CGImageGetBitmapInfo(neededImage.CGImage)); 
    CGContextConcatCTM(ctx, transform); 
    switch (neededImage.imageOrientation) { 
     case UIImageOrientationLeft: 
     case UIImageOrientationLeftMirrored: 
     case UIImageOrientationRight: 
     case UIImageOrientationRightMirrored: 
      // Grr... 
      CGContextDrawImage(ctx, CGRectMake(0,0,neededImage.size.height,neededImage.size.width), neededImage.CGImage); 
      break; 

     default: 
      CGContextDrawImage(ctx, CGRectMake(0,0,neededImage.size.width,neededImage.size.height), neededImage.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; 
} 

Я не конечно, насколько это полезно для вас, но я надеюсь, что это помогло :)

12

Для Swift 2.1

Добавьте следующее в качестве расширения UIImage,

extension UIImage { 
    func fixOrientation() -> UIImage { 
     if self.imageOrientation == UIImageOrientation.Up { 
      return self 
     } 

     UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) 
     self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height)) 
     let normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return normalizedImage; 
    } 
} 

Пример использования:

let cameraImage = //image captured from camera 
let orientationFixedImage = cameraImage.fixOrientation() 
+0

Очень полезно. Спасибо!! –

+0

Вероятно, лучший ответ до сих пор, который не использует взломы fuctions вместе. Очень красивый. – Munib

+0

@ return0 Спасибо! Пожалуйста, подумайте над ответом. – Rao

1

Попробуйте, Вы можете использовать

NSData *somenewImageData = UIImageJPEGRepresentation(newimg,1.0); 

вместо

NSData *somenewImageData = UIImagePNGRepresentation(newimg); 
12

Swift 3.1 версия расширения UIImage разместил Рао:

extension UIImage { 
    func fixOrientation() -> UIImage { 
     if self.imageOrientation == UIImageOrientation.up { 
      return self 
     } 
     UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) 
     self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) 
     if let normalizedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() { 
      UIGraphicsEndImageContext() 
      return normalizedImage 
     } else { 
      return self 
     } 
    } 
} 

Использование:

let cameraImage = //image captured from camera 
let orientationFixedImage = cameraImage.fixOrientation()