iOS: L'Image est pivotée à 90 degrés après avoir été enregistrée en tant que données de représentation PNG

J'ai fait suffisamment de recherches pour que cela fonctionne mais je ne suis pas capable de le réparer. Après avoir pris une photo de la caméra tant que j'ai une image stockée en tant Qu'UIImage, c'est bien, mais dès que j'ai stocké cette image en tant que représentation PNG, elle tourne à 90 degrés.

Voici mon code et toutes les choses que j'ai essayées:

- (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];
}

Ici fixOrientation et scaleAndRotateImage fonctions prises à partir de ici et ici respectivement. Ils fonctionnent bien et font pivoter l'image lorsque je les applique sur UIImage mais ne fonctionne pas si je sauvegarde l'image en tant que représentation PNG et les applique.

Veuillez renvoyer l'image suivante après l'exécution des fonctions ci-dessus:

La première photo est originale, la seconde est enregistrée, et les troisième et quatrième après l'application des fonctions fixorientation et scaleandrotate sur l'image enregistrée

34
demandé sur Community 2012-06-01 16:23:12

8 réponses

À partir d'iOS 4.0 lorsque l'appareil photo prend une photo, il ne la fait pas pivoter avant d'enregistrer, IL

Définit simplement un indicateur de rotation dans les données EXIF du JPEG.Si vous enregistrez un UIImage au format JPEG, IL

Définit l'indicateur de rotation.Les png ne prennent pas en charge un indicateur de rotation, donc si vous enregistrez un UIImage en tant que

PNG, il sera tourné incorrectement et n'aura pas d'indicateur pour le réparer. Donc, si vous voulez PNG

Images vous devez les faire pivoter vous - même, pour cela vérifiez ceci lien.

62
répondu Mudit Bajpai 2017-05-23 11:54:50

Version Swift 3.1 de L'extension UIImage publiée par Rao:

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
        }
    }
}

Utilisation:

let cameraImage = //image captured from camera
let orientationFixedImage = cameraImage.fixOrientation()
19
répondu Andreas 2017-04-03 08:55:23

Pour Swift 2.1

Ajoutez ce qui suit comme extension 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;
    }
}

Exemple d'utilisation:

let cameraImage = //image captured from camera
let orientationFixedImage = cameraImage.fixOrientation()
15
répondu Rao 2016-09-20 13:29:43

J'ai trouvé les conseils suivants extrêmement utiles:

1. la sortie naturelle est paysage

2. .largeur / .la hauteur SONT affectés par .imageOrientation

3 Utilisez une dimension courte plutôt que .largeur


(1) la sortie' naturelle ' de la caméra pour les images fixes est paysage.

C'est contre-intuitif. portrait est le seul moyen offert par UIImagePickerController etc. Mais vous obtiendrez UIImageOrientationRight comme orientation "normale" lorsque vous utilisez la caméra portrait "normale"

(la façon dont je me souviens de cela - la sortie naturelle pour la vidéo est (bien sûr) paysage; donc les images fixes sont les mêmes-même si l'iPhone est tout au sujet de portrait.)


(2) .la largeur et la .hauteur sont en effet affectés par la .imageOrientation!!!!!!!!!

Assurez-vous de le faire, et essayez-le dans les deux sens sur votre iPhone,

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

Vous verrez que le.la hauteur et la .largeur swap, "même si" les pixels réels sont paysage.


(3) simplement en utilisant la "dimension courte" plutôt que .largeur, peut souvent résoudre de nombreux problèmes

J'ai trouvé cela incroyablement utile. Dites que vous voulez peut-être le carré supérieur de l'image:

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

Cela ne fonctionnera pas, vous obtiendrez une image écrasée, lorsque la caméra est ("vraiment") tenue paysage.

Cependant, si vous le faites très simplement

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

Alors "tout est corrigé" et vous en fait "n'avez pas besoin de vous inquiéter à propos de " {[16] } le drapeau d'orientation. Encore une fois, le point (3) n'est pas un remède, mais il résout très souvent tous les problèmes.

J'espère que cela aidera quelqu'un à gagner du temps.

6
répondu Fattie 2014-08-30 14:36:45

J'ai trouvé ce code ici , qui l'a effectivement corrigé pour moi. Pour mon application, j'ai pris une photo et l'ai enregistrée, et chaque fois que je l'ai chargée, la rotation ennuyeuse serait attachée (j'ai regardé, et c'est apparemment quelque chose à voir avec L'EXIF et la façon dont l'iPhone prend et stocke des images). Ce code l'a corrigé pour moi. Je dois dire, c'était à l'origine comme un ajout à une classe / une extension /catégorie (vous pouvez trouver l'original à partir du lien. Je l'ai utilisé comme ci-dessous comme une méthode simple, comme je Je ne voulais pas vraiment faire toute une classe ou une catégorie pour cela. J'ai seulement utilisé portrait, mais je pense que le code fonctionne pour n'importe quelle orientation. Je ne suis pas sûr cependant

Diatribe sur, voici le code:

- (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;
}

Je ne suis pas sûr de l'utilité de ce sera pour vous, mais j'espère que cela a aidé:)

2
répondu Septronic 2016-07-05 17:10:06

Essayez ceci, Vous pouvez utiliser

NSData *somenewImageData = UIImageJPEGRepresentation(newimg,1.0);

Au Lieu de

NSData *somenewImageData = UIImagePNGRepresentation(newimg);
2
répondu vijay 2017-01-31 05:39:57

Pls essayer le code suivant

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];

Et

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];

J'ai référencé à partir du lien suivant ont chercher plus détail

Cordialement :-)

1
répondu NIKHIL 2012-06-01 12:40:50

Essayez ce code:

NSData *imageData = UIImageJPEGRepresentation(delegate.originalPhoto,100);
0
répondu Mubasher 2015-05-26 12:54:45