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:
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.
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()
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()
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.
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é:)
Essayez ceci, Vous pouvez utiliser
NSData *somenewImageData = UIImageJPEGRepresentation(newimg,1.0);
Au Lieu de
NSData *somenewImageData = UIImagePNGRepresentation(newimg);
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 :-)
Essayez ce code:
NSData *imageData = UIImageJPEGRepresentation(delegate.originalPhoto,100);