web-dev-qa-db-fra.com

Comment faire pivoter UIImage

Je développe une application iOS pour iPad. Existe-t-il un moyen de faire pivoter un UIImage de 90 °, puis de l'ajouter à un UIImageView? J'ai essayé beaucoup de codes différents mais aucun n'a fonctionné ...

Merci!

18
Marti Serra Vivancos

Vous pouvez faire pivoter UIImageView lui-même avec:

UIImageView *iv = [[UIImageView alloc] initWithImage:image];
iv.transform = CGAffineTransformMakeRotation(M_PI_2);

Ou si vous voulez vraiment changer d'image, vous pouvez utiliser le code de cette réponse , cela fonctionne.

22
kovpas

Pour faire pivoter les pixels, vous pouvez utiliser ce qui suit. Cela crée un UIImage intermédiaire avec des métadonnées pivotées et le rend dans un contexte d'image avec des dimensions largeur/hauteur transposées. L'image résultante fait pivoter les pixels (c'est-à-dire l'image CG sous-jacente)

- (UIImage*)rotateUIImage:(UIImage*)sourceImage clockwise:(BOOL)clockwise
{
    CGSize size = sourceImage.size;
    UIGraphicsBeginImageContext(CGSizeMake(size.height, size.width));
    [[UIImage imageWithCGImage:[sourceImage CGImage] scale:1.0 orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft] drawInRect:CGRectMake(0,0,size.height ,size.width)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Il existe d'autres valeurs possibles qui peuvent être transmises pour le paramètre d'orientation pour obtenir une rotation à 180 degrés et des retournements, etc.

17
Jason Crocker

Cela fera pivoter une image de n'importe quel degré.

Notez que cela fonctionne également 2x et 3x rétine

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees {
    CGFloat radians = DegreesToRadians(degrees);

    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.size.width, self.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(radians);
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, [[UIScreen mainScreen] scale]);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);

    CGContextRotateCTM(bitmap, radians);

    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2 , self.size.width, self.size.height), self.CGImage );

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}
9
RyanG

Il y a aussi imageWithCIImage:scale:orientation si vous vouliez faire pivoter le UIImage pas le UIImageView

avec l'une de ces orientations:

typedef enum {
   UIImageOrientationUp,
   UIImageOrientationDown,   // 180 deg rotation
   UIImageOrientationLeft,   // 90 deg CW
   UIImageOrientationRight,   // 90 deg CCW
   UIImageOrientationUpMirrored,    // vertical flip
   UIImageOrientationDownMirrored,  // horizontal flip
   UIImageOrientationLeftMirrored,  // 90 deg CW then perform horizontal flip
   UIImageOrientationRightMirrored, // 90 deg CCW then perform vertical flip
} UIImageOrientation;
7
Jaybit

Voici la version Swift du code Objective C de @ RyanG en tant qu'extension de UIImage:

extension UIImage {

    func rotate(byDegrees degree: Double) -> UIImage {
        let radians = CGFloat(degree*M_PI)/180.0 as CGFloat
        let rotatedViewBox = UIView(frame: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        let t = CGAffineTransform(rotationAngle: radians)
        rotatedViewBox.transform = t
        let rotatedSize = rotatedViewBox.frame.size
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
        let bitmap = UIGraphicsGetCurrentContext()
        CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);

        bitmap!.rotate(by: radians);

        bitmap!.scaleBy(x: 1.0, y: -1.0);
        CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2 , self.size.width, self.size.height), self.CGImage );

        let newImage = UIGraphicsGetImageFromCurrentImageContext()

        return newImage
    }

}

L'usage est image.rotate(degree).

5
RawMean

Avec Swift, vous pouvez faire pivoter une image en faisant:

var image: UIImage = UIImage(named: "headerBack.png")
var imageRotated: UIImage = UIImage(CGImage: image.CGImage, scale:1, orientation: UIImageOrientation.UpMirrored)
4
rsc
UIImage *img = [UIImage imageWithName@"aaa.png"];
UIImage *image = [UIImage imageWithCGImage:img.CGImage scale:1.0 orientation:UIImageOrientationRight];
4
vualoaithu

Merci Jason Crocker, cela a résolu mon problème. Une seule correction mineure, hauteur et largeur d'échange aux deux endroits et aucune distorsion ne se produit, c.-à-d.

UIGraphicsBeginImageContext(CGSizeMake(size.width, size.height));
[[UIImage imageWithCGImage:[sourceImage CGImage] scale:1.0 orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft]  drawInRect:CGRectMake(0,0,size.width,size.height)]; 

Mon problème n'a pas pu être résolu par CGContextRotateCTM, je ne sais pas pourquoi. Mon problème est que je transmets mon image à un serveur et qu'elle était toujours affichée à 90 degrés. Vous pouvez facilement tester si vos images vont fonctionner dans le monde non Apple en copiant l'image dans un programme MS Office que vous exécutez sur votre Mac.

1
Steig Hallquist

C'est ce que j'ai fait quand j'ai voulu changer l'orientation d'une image (pivoter de 90 degrés dans le sens des aiguilles d'une montre).

//Checking for the orientation ie, image taken from camera is in portrait or not.
if(yourImage.imageOrientation==3)
{
    //Image is in portrait mode.
    yourImage=[self imageToRotate:yourImage RotatedByDegrees:90.0];
}

- (UIImage *)image:(UIImage *)imageToRotate RotatedByDegrees:(CGFloat)degrees
{
    CGFloat radians = degrees * (M_PI / 180.0);

    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, image.size.height, image.size.width)];
    CGAffineTransform t = CGAffineTransformMakeRotation(radians);
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, [[UIScreen mainScreen] scale]);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(bitmap, rotatedSize.height / 2, rotatedSize.width / 2);

    CGContextRotateCTM(bitmap, radians);

    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-image.size.width / 2, -image.size.height / 2 , image.size.height, image.size.width), image.CGImage );
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

L'image pivotée peut avoir une taille> = 15 Mo (d'après mon expérience). Vous devez donc le compresser et l'utiliser. Sinon, vous pourriez rencontrer un crash provoquant une pression mémoire. Le code que j'ai utilisé pour la compression est donné ci-dessous.

NSData *imageData = UIImageJPEGRepresentation(yourImage, 1);
//1 - it represents the quality of the image.
NSLog(@"Size of Image(bytes):%d",[imageData length]);
//Here I used a loop because my requirement was, the image size should be <= 4MB.
//So put an iteration for more than 1 time upto when the image size is gets <= 4MB.
for(int loop=0;loop<100;loop++)
{
    if([imageData length]>=4194304)  //4194304 = 4MB in bytes.
    {
        imageData=UIImageJPEGRepresentation(yourImage, 0.3);
        yourImage=[[UIImage alloc]initWithData:imageData];
    }
    else
    {
        NSLog(@"%d time(s) compressed.",loop);
        break;
    }
}

Maintenant, votre yourImage peut être utilisé n'importe où .. Bon codage ...

1
soorej babu

Une autre façon de procéder serait de rendre à nouveau l'UIImage à l'aide de Core Graphics.

Une fois que vous avez le contexte, utilisez CGContextRotateCTM.

Plus d'informations sur ce Apple Doc

1
luksfarris