CGImageCreateWithImageInRect ne recadre pas correctement

J'utilise CGImageCreateWithImageInRect pour recadrer une photo. Mon application permet à l'user de déplacer / agrandir une image jusqu'à ce qu'elle remplisse une vue 316 x 316, puis je veux qu'elle recadre toute zone en dehors de la boîte et save l'image en tant que UIImage. Je détermine l'origine de la culture en prenant la valeur absolue de l'origine imageview x et y car cela me ramène à 0,0 de la vue / boîte qui contient l'imageview. Voici le code:

CGRect croppedRect = CGRectMake(fabs(widthDistanceToOrigin), fabs(HeightDistanceToOrigin), 316, 316); CGImageRef croppedImageRef = CGImageCreateWithImageInRect(image.CGImage, croppedRect); UIImage *croppedImage = [UIImage imageWithCGImage: croppedImageRef scale: 1 / (imageScale) orientation: image.imageOrientation]; CGImageRelease(croppedImageRef); 

Cela me rend fou, je ne peux pas l'get pour recadrer la zone que je veux. Je l'ai à l'échelle correctement, mais le problème semble être avec l'origine x et y de la récolte rect, c'est un peu hors de la zone qu'il devrait prendre (et parfois je reçois des résultats bizarres).

En outre, il semble que pour les images sockets avec l'appareil photo du téléphone, je dois tout multiplier dans ma récolte recto par 2 pour que la taille soit correcte. Très étrange.

Donc, je me request, est-ce que quelqu'un sait comment résoudre ce problème, ou est-ce que quelqu'un a une meilleure façon de recadrer (et s'il vous plaît gardez à l'esprit que je dois recadrer une zone dans ma photo). Merci!

Il y a tellement de messages sur ce sujet avec tous les mêmes réponses exactes, à utiliser: CGImageCreateWithImageInRect mais aucun d'entre eux ne résout complètement le problème de positionnement incorrect de ce qui essaie d'être recadré.

Cependant, un seul thread (enfoui profondément à l'intérieur), a un détail mineur qui manque à tout le monde … Comment recadrer un UIImageView à un nouveau UIImage en mode 'ajustement de l'apparence'?

le paramètre 'rect' qui va dans CGImageCreateWithImageInRect (image.CGImage, croppedRect) doit représenter (tiré de) l'UIImage, pas le UIImageView.

Cela devrait résoudre le problème du positionnement erroné sur le système de coordonnées.

  - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info { oImage = [info valueForKey:UIImagePickerControllerOriginalImage]; NSLog(@"Original Image size width: %fx height: %f", oImage.size.width, oImage.size.height); // crop image according to what the image picker view is displaying CGRect rect = CGRectMake(0, 40, 960.0f, 960.0f); // note: 960 x 1280 is what natively comes from capturing and image nImage = [BGViewModifiers cropImage:oImage inRect:rect]; // scale image down for display and creating kombie CGSize size = CGSizeMake(320.0f, 320.0f); nImage = [BGViewModifiers imageFromImage:nImage scaledToSize:size]; NSLog(@"New Image size width: %fx height: %f", [nImage size].width, [nImage size].height); } //ref: http://stackoverflow.com/a/25293588/2298002 + (UIImage *)cropImage:(UIImage*)image inRect:(CGRect)rect { double (^rad)(double) = ^(double deg) { return deg / 180.0 * M_PI; }; CGAffineTransform rectTransform; switch (image.imageOrientation) { case UIImageOrientationLeft: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height); break; case UIImageOrientationRight: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0); break; case UIImageOrientationDown: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height); break; default: rectTransform = CGAffineTransformIdentity; }; rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale); CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectApplyAffineTransform(rect, rectTransform)); UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; CGImageRelease(imageRef); return result; } + (UIImage*)imageFromImage:(UIImage*)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContext( newSize ); [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Je voudrais fournir plus d'information / réponse pour ceci basé sur ma propre expérience.

De la UIImage (et donc CGImageCreateWithImageInRect: , (0, 0) est en bas à gauche. Lors de la détermination du carré de recadrage, vous pouvez simplement calculer le carré en fonction de l'orientation portrait standard, puis utiliser la méthode dans la réponse de @ serre (affichée à nouveau ici pour plus de clarté et modifiée pour utiliser CGFloat pour corriger une erreur de CGFloat .

 - (UIImage *)cropImage:(UIImage*)image toRect:(CGRect)rect { CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) { return deg / 180.0f * (CGFloat) M_PI; }; // determine the orientation of the image and apply a transformation to the crop rectangle to shift it to the correct position CGAffineTransform rectTransform; switch (image.imageOrientation) { case UIImageOrientationLeft: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height); break; case UIImageOrientationRight: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0); break; case UIImageOrientationDown: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height); break; default: rectTransform = CGAffineTransformIdentity; }; // adjust the transformation scale based on the image scale rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale); // apply the transformation to the rect to create a new, shifted rect CGRect transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform); // use the rect to crop the image CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare); // create a new UIImage and set the scale and orientation appropriately UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; // memory cleanup CGImageRelease(imageRef); return result; } 

Ce code décale le carré de la récolte afin qu'il soit dans la bonne position relative.

J'ai trouvé le problème. J'essayais d'attraper la zone de culture avant d'agrandir l'image. Maintenant, je dois comprendre comment réduire l'image avant de faire "CGImageCreateWithImageInRect".