2010-05-18 7 views
15

J'ai un UIImageView avec une image. J'ai fait pivoter l'image avant d'afficher en définissant la propriété de transformation de UIImageView à CGAffineTransformMakeRotation (angle) où angle est l'angle en radians. Je veux être capable de créer un autre UIImage qui correspond à la version pivotée que je peux voir à mon avis.Création d'un UIImage à partir d'un UIImageView pivoté

Je suis presque là, en faisant tourner le contexte d'image j'obtenir une image pivotée:

- (UIImage *) rotatedImageFromImageView: (UIImageView *) imageView 
{ 
    UIImage *rotatedImage; 

    // Get image width, height of the bounding rectangle 
    CGRect boundingRect = [self getBoundingRectAfterRotation: imageView.bounds byAngle:angle]; 

    // Create a graphics context the size of the bounding rectangle 
    UIGraphicsBeginImageContext(boundingRect.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Rotate and translate the context 
    CGAffineTransform ourTransform = CGAffineTransformIdentity; 
    ourTransform = CGAffineTransformConcat(ourTransform, CGAffineTransformMakeRotation(angle)); 

    CGContextConcatCTM(context, ourTransform); 

    // Draw the image into the context 
    CGContextDrawImage(context, CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height), imageView.image.CGImage); 

    // Get an image from the context 
    rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)]; 

    // Clean up 
    UIGraphicsEndImageContext(); 
    return rotatedImage; 
} 

Cependant, l'image ne tourne pas autour de son centre. J'ai essayé toutes sortes de transformations concaténées avec ma rotation pour l'obtenir de tourner autour du centre mais en vain. Est-ce que je manque un tour? Est-ce même possible puisque je fais tourner le contexte et non l'image? Désireux de faire ce travail maintenant, alors toute aide serait appréciée.

Dave

EDIT: On m'a demandé à plusieurs reprises pour mon code boundingRect, donc la voici:

- (CGRect) getBoundingRectAfterRotation: (CGRect) rectangle byAngle: (CGFloat) angleOfRotation { 
    // Calculate the width and height of the bounding rectangle using basic trig 
    CGFloat newWidth = rectangle.size.width * fabs(cosf(angleOfRotation)) + rectangle.size.height * fabs(sinf(angleOfRotation)); 
    CGFloat newHeight = rectangle.size.height * fabs(cosf(angleOfRotation)) + rectangle.size.width * fabs(sinf(angleOfRotation)); 

    // Calculate the position of the origin 
    CGFloat newX = rectangle.origin.x + ((rectangle.size.width - newWidth)/2); 
    CGFloat newY = rectangle.origin.y + ((rectangle.size.height - newHeight)/2); 

    // Return the rectangle 
    return CGRectMake(newX, newY, newWidth, newHeight); 
} 
+0

Qu'est-ce que cette fonction 'getBoundingRectAfterRotation'? – bmdhacks

+0

Salut @bmdhacks getBoundingRectAfterRotation est une méthode que j'ai créée, vous ne la trouverez donc pas dans les classes Cocoa-Touch. Il prend un rect et un angle comme arguments et renvoie un nouveau CGRect qui engloberait le rect d'origine s'il était tourné par l'angle donné. –

+0

Salut @bmdhacks en raison de la demande populaire ont ajouté la méthode dans une édition à ma question initiale. –

Répondre

22

OK - enfin il me semble avoir fait. Tous les commentaires sur l'exactitude seraient utiles ... besoin d'une traduction, une rotation, une échelle et un décalage de la position rectangle de dessin pour le faire fonctionner. Le code est ici:

CGAffineTransform transform = CGAffineTransformIdentity; 
transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2); 
transform = CGAffineTransformRotate(transform, angle); 
transform = CGAffineTransformScale(transform, 1.0, -1.0); 

CGContextConcatCTM(context, transform); 

// Draw the image into the context 
CGContextDrawImage(context, CGRectMake(-imageView.image.size.width/2, -imageView.image.size.height/2, imageView.image.size.width, imageView.image.size.height), imageView.image.CGImage); 

// Get an image from the context 
rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)]; 
+1

pourquoi avez-vous besoin de 'transform = CGAffineTransformScale (transformer, 1.0, -1.0);' ? – Hlung

+3

CoreGraphics utilise un système de coordonnées dont l'origine est en bas à gauche. Les objets UIKit utilisent une origine en haut à gauche avec l'axe des y croissant lorsque vous vous déplacez vers le bas de l'écran. Cette transformation inverse l'axe des y pour s'assurer que l'image est dessinée correctement. –

+1

Merci! J'avais du mal à dessiner l'image sur le contexte avec la traduction, la rotation et la mise à l'échelle. J'ai essayé 'drawInRect:' de UIImage et je traduis le contexte mais il tourne toujours en haut à gauche (0,0). Votre solution est la seule qui fonctionne! :) – Hlung