35 votes

Le redimensionnement d’UIimages extrait de l’appareil fait également pivoter l’UIimage?

Je suis UIimages de la caméra et de les assigner à UIImageViews à être affiché. Quand je fais cela, la caméra me donne une résolution de 1200 x 1600 pixels pour une image que j'ai ensuite affecter à une UIImageView dans mon Application. L'image est affichée comme prévu dans l'affichage de l'image sous cette condition. Cependant, quand j'essaye de REDIMENSIONNER l'extrait UIImage avant de l'affecter à la UIImageView, l'image est en cours de redimensionnement comme prévu, mais il y a un problème quelque part (dans le REDIMENSIONNEMENT de code?) mon UIImage est prise en ROTATION... Comme un résultat, quand j'assigne le redimensionnement UIImage à une UIImageView l'image est pivotée de 90 degrés et semble tendu que le rapport d'aspect (1200 x 1600 pixels) est inchangé...

J'utilise cela pour obtenir une UIImage de la Caméra:

- (void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{

    	myImg = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    	myResizedImg = [self resizeImage:myImg width:400 height:533];
    	[myImageView setImage:myResizedImg];

}

Je me sers de ce pour la redimensionner:

-(UIImage *)resizeImage:(UIImage *)anImage width:(int)width height:(int)height
{

    CGImageRef imageRef = [anImage CGImage];

    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);

    if (alphaInfo == kCGImageAlphaNone)
    alphaInfo = kCGImageAlphaNoneSkipLast;


    CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);

    CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);

    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage *result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);
    CGImageRelease(ref);

    return result;	
}

QUESTION: Comment REDIMENSIONNER une UIImage tiré de l'Appareil photo SANS faire pivoter les pixels?

61voto

Itay Points 1075

La raison que votre code ne fonctionne pas est parce que le imageOrientation sur le code que vous avez à faire est de ne pas être pris en compte. Plus précisément, si le imageOrientation est à droite/à gauche, puis vous le besoin à la fois de faire pivoter l'image et le swap largeur/hauteur. Voici un peu de code pour faire ceci:

-(UIImage*)imageByScalingToSize:(CGSize)targetSize
{
	UIImage* sourceImage = self; 
	CGFloat targetWidth = targetSize.width;
	CGFloat targetHeight = targetSize.height;

	CGImageRef imageRef = [sourceImage CGImage];
	CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
	CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

	if (bitmapInfo == kCGImageAlphaNone) {
		bitmapInfo = kCGImageAlphaNoneSkipLast;
	}

	CGContextRef bitmap;

	if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
		bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

	} else {
		bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

	}	

	if (sourceImage.imageOrientation == UIImageOrientationLeft) {
		CGContextRotateCTM (bitmap, radians(90));
		CGContextTranslateCTM (bitmap, 0, -targetHeight);

	} else if (sourceImage.imageOrientation == UIImageOrientationRight) {
		CGContextRotateCTM (bitmap, radians(-90));
		CGContextTranslateCTM (bitmap, -targetWidth, 0);

	} else if (sourceImage.imageOrientation == UIImageOrientationUp) {
		// NOTHING
	} else if (sourceImage.imageOrientation == UIImageOrientationDown) {
		CGContextTranslateCTM (bitmap, targetWidth, targetHeight);
		CGContextRotateCTM (bitmap, radians(-180.));
	}

	CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef);
	CGImageRef ref = CGBitmapContextCreateImage(bitmap);
	UIImage* newImage = [UIImage imageWithCGImage:ref];

	CGContextRelease(bitmap);
	CGImageRelease(ref);

	return newImage; 
}

Cela permettra de redimensionner votre image et faites-la tourner pour l'orientation correcte. Si vous avez besoin de la définition du radian, c'est:

static inline double radians (double degrees) {return degrees * M_PI/180;}

La réponse de Daniel a donné est également correct, mais il souffre du problème qu'il n'est pas thread-safe, depuis que vous utilisez UIGraphicsBeginImageContext(). Depuis le code ci-dessus utilise uniquement la CG fonctions, vous êtes tous ensemble. J'ai également une fonction similaire pour redimensionner et faire le bon aspect de remplissage sur les images - permettez-moi de savoir si c'est ce que vous cherchez.

Note: j'ai eu la fonction d'origine de ce post, et fait quelques modifications pour le faire fonctionner sur des fichiers Jpeg.

11voto

Daniel Points 16707

J'ai eu ce problème aussi avec certains des codes là-bas, j'ai trouvé ce code qui fonctionne, vérifiez-le, laissez-moi savoir ce que vous trouvez

 + (UIImage*)imageWithImage:(UIImage*)image 
               scaledToSize:(CGSize)newSize;
{
   UIGraphicsBeginImageContext( newSize );
   [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
   UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   return newImage;
}
 

1voto

wzbozon Points 2851

Si vous souhaitez créer une image carrée à partir d'une image rectangle (qu'elle soit horizontale ou verticale) en la coupant en largeur ou en hauteur des deux côtés, utilisez mon code. La différence est que je ne m'étire pas, mais je coupe. Je l'ai fait à partir du code supérieur par modification:

 //Cropping _image to fit it to the square by height or width

CGFloat a = _image.size.height;
CGFloat b = _image.size.width;
CGRect cropRect;

if (!(a==b)) {
    if (a<b) {
        cropRect = CGRectMake((b-a)/2.0, 0, a, a);
        b = a;
    }
    else if (b<a) {
        cropRect = CGRectMake(0, (a-b)/2.0, b, b);
        a = b;
    }

    CGImageRef imageRef = CGImageCreateWithImageInRect([_image CGImage], cropRect);

    UIImage* sourceImage = _image; 
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    CGContextRef bitmap;
    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
        bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

    } else {
        bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    }

    if (sourceImage.imageOrientation == UIImageOrientationLeft) {
        CGContextRotateCTM (bitmap, radians(90));
        CGContextTranslateCTM (bitmap, 0, -a);

    } else if (sourceImage.imageOrientation == UIImageOrientationRight) {
        CGContextRotateCTM (bitmap, radians(-90));
        CGContextTranslateCTM (bitmap, -a, 0);

    } else if (sourceImage.imageOrientation == UIImageOrientationUp) {
        // NOTHING
    } else if (sourceImage.imageOrientation == UIImageOrientationDown) {
        CGContextTranslateCTM (bitmap, a, a);
        CGContextRotateCTM (bitmap, radians(-180.));
    }

    CGContextDrawImage(bitmap, CGRectMake(0, 0, a, a), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    _image = [UIImage imageWithCGImage:ref];
    CGImageRelease(imageRef);
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X