2010-08-24 9 views
42

Ich möchte Bilder von UIImagePickerController laden und dann das ausgewählte Foto im Dokumentverzeichnis meiner App speichern.UIIagePNGRepräsentationsprobleme?/Bilder um 90 Grad gedreht

UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 
NSData *data1 = UIImagePNGRepresentation(image); 

NSString *fileName = "1.png"; 
NSString *path = //get Document path, then add fileName 
BOOL succ = [data1 writeToFile:path atomically:YES]; 

aber nachdem ich das Bild auf mein Dokument speichern, fand ich, dass, wurde das Bild um 90 Grad gedreht wird, dann ändere ich die Methode UIImagePNGRepresentation zu UIImageJPEGRepresentation, diesmal ist es in Ordnung, kann jeder wissen, was das Problem ist?

+0

Hatte das gleiche Problem. – ZaBlanc

+0

möglich Duplikat von [iOS UIImagePickerController Ergebnis Bildausrichtung nach dem Upload] (http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-bild-orientation-after-upload) –

Antwort

70

Ich hatte das gleiche Problem und nur den Grund herausgefunden: beginnend mit iOS 4.0, wenn die Kamera ein Foto macht es nicht vor dem Speichern dreht es einfach ein Rotations-Flag in den EXIF-Daten des JPEG.

Wenn Sie ein UIImage als JPEG speichern, wird das Rotationsflag gesetzt.

PNGs unterstützen kein Rotations-Flag. Wenn Sie also ein UIImage als PNG speichern, wird es falsch gedreht und es ist kein Flag gesetzt, um es zu reparieren. Also, wenn Sie PNGs wollen, müssen Sie sie selbst drehen.

Ich würde dies einen Fehler in der PNG-Speicherfunktion nennen, aber das ist nur eine Meinung (sie sollten Sie zumindest davor warnen).

+0

vielen Dank. – disorderdev

+0

Ich verbrachte wahrscheinlich eine Stunde oder so versuchen, meine PNG CGImageSource (erstellt aus Daten), um richtig zu drehen, wenn der Daumen erstellt wurde ... Einfügen Exif Daten in meine CGImageSource Erstellungsoptionen usw. usw. und UIImageJPEGRepresentation behoben es sofort ! Vielen Dank! – taber

+3

@jasongregori: Selbst wenn es als JPEG gespeichert wird, löst es mein Problem nicht. Bild dreht sich immer noch. –

14

Ich löse dieses Problem mit dem folgenden Code.

- (UIImage *)scaleAndRotateImage:(UIImage *)image 
{ 
    int kMaxResolution = 640; 

    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; 
} 
+0

Ich mag diesen Code und irgendwie ist es der einzige, der in Bezug auf die Rotation meines Bildes funktioniert. Wie auch immer, ich habe Probleme mit iOS 7.1 und dem ARC-Zyklus. Irgendeine Idee, wo das Problem liegen könnte? –

+0

Vielen Dank dafür! Lief wie am Schnürchen! Ich habe es für mein aktuelles Projekt in swift 2.0 übersetzt. Hier ist ein Kern: https: //gist.github.com/fnk0/2e108700bdbe4a92766c –

+0

@MarcusGabilheri Wie würde ich Ihren Code verwenden, um 90 Grad zu drehen? – alex

2

Die folgende schnelle Funktion behebt das Problem.

var rotatedCopy: UIImage { 
    if (imageOrientation == UIImageOrientation.Up) { 
     return self 
    } 

    UIGraphicsBeginImageContext(size) 

    drawInRect(CGRect(origin: CGPoint.zeroPoint, size: size)) 
    let copy = UIGraphicsGetImageFromCurrentImageContext() 

    UIGraphicsEndImageContext() 

    return copy 
} 

Yup es ist so einfach, nur weil die drawInRect Funktion Bildausrichtung in Betracht ziehen wird.

+0

Wie würde ich das verwenden? Momentan sieht mein imageHolder-Code so aus: 'invoiceImageHolder.image = loadImageFromPath (fileInDocumentsDirectory ((\ (imagePath!)"))) 'und ich erhalte Fehler Verwendung der unaufgelösten ID 'imageOrientation' – alex

9

Versuchen Sie dieses:

func rotateImage(image: UIImage) -> UIImage { 

    if (image.imageOrientation == UIImageOrientation.Up) { 
     return image 
    } 

    UIGraphicsBeginImageContext(image.size) 

    image.drawInRect(CGRect(origin: CGPoint.zero, size: image.size)) 
    let copy = UIGraphicsGetImageFromCurrentImageContext() 

    UIGraphicsEndImageContext() 

    return copy 
} 
+0

Vielen Dank. Dies vor dem Speichern des Bildes als .png löste es für mich. – Alexandros

1

Ich habe diese UIImage Erweiterung erstellt, dieses Problem mit UIImagePNGRepresentation zu beheben, basierend auf this response. Also schlage ich vor, diese Klasse func UIImage.PNGRepresentation(img: UIImage) anstelle von UIKit func UIImagePNGRepresentation zu verwenden.

Swift 3-Code:

// MyUIImage.swift 
// MyEasyMovie-Public-App 
// 
// Created by Ahmed Zahraz on 19/12/2016. 
// Copyright © 2016 AhmedZahraz. All rights reserved.  

import Foundation 
import UIKit 

extension UIImage { 


    public class func PNGRepresentation(_ img: UIImage) -> Data? { 
     // No-op if the orientation is already correct 
     if (img.imageOrientation == UIImageOrientation.up) { 
      return UIImagePNGRepresentation(img); 
     } 
     // 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. 
     var transform:CGAffineTransform = CGAffineTransform.identity 

     if (img.imageOrientation == UIImageOrientation.down 
      || img.imageOrientation == UIImageOrientation.downMirrored) { 

      transform = transform.translatedBy(x: img.size.width, y: img.size.height) 
      transform = transform.rotated(by: CGFloat(M_PI)) 
     } 

     if (img.imageOrientation == UIImageOrientation.left 
      || img.imageOrientation == UIImageOrientation.leftMirrored) { 

      transform = transform.translatedBy(x: img.size.width, y: 0) 
      transform = transform.rotated(by: CGFloat(M_PI_2)) 
     } 

     if (img.imageOrientation == UIImageOrientation.right 
      || img.imageOrientation == UIImageOrientation.rightMirrored) { 

      transform = transform.translatedBy(x: 0, y: img.size.height); 
      transform = transform.rotated(by: CGFloat(-M_PI_2)); 
     } 

     if (img.imageOrientation == UIImageOrientation.upMirrored 
      || img.imageOrientation == UIImageOrientation.downMirrored) { 

      transform = transform.translatedBy(x: img.size.width, y: 0) 
      transform = transform.scaledBy(x: -1, y: 1) 
     } 

     if (img.imageOrientation == UIImageOrientation.leftMirrored 
      || img.imageOrientation == UIImageOrientation.rightMirrored) { 

      transform = transform.translatedBy(x: img.size.height, y: 0); 
      transform = transform.scaledBy(x: -1, y: 1); 
     } 


     // Now we draw the underlying CGImage into a new context, applying the transform 
     // calculated above. 
     let ctx:CGContext = CGContext(data: nil, width: Int(img.size.width), height: Int(img.size.height), 
             bitsPerComponent: img.cgImage!.bitsPerComponent, bytesPerRow: 0, 
             space: img.cgImage!.colorSpace!, 
             bitmapInfo: img.cgImage!.bitmapInfo.rawValue)! 

     ctx.concatenate(transform) 


     if (img.imageOrientation == UIImageOrientation.left 
      || img.imageOrientation == UIImageOrientation.leftMirrored 
      || img.imageOrientation == UIImageOrientation.right 
      || img.imageOrientation == UIImageOrientation.rightMirrored 
      ) { 


      ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.height,height:img.size.width)) 

     } else { 
      ctx.draw(img.cgImage!, in: CGRect(x:0,y:0,width:img.size.width,height:img.size.height)) 
     } 


     // And now we just create a new UIImage from the drawing context 
     let cgimg:CGImage = ctx.makeImage()! 
     let imgEnd:UIImage = UIImage(cgImage: cgimg) 

     return UIImagePNGRepresentation(imgEnd) 
    } 

}