2013-02-13 9 views
15

Ich entwickle eine iOS App für iPad. Gibt es eine Möglichkeit, ein UIImage um 90º zu drehen und dann zu einem UIImageView hinzuzufügen? Ich habe viele verschiedene Codes ausprobiert, aber keine funktionierte ...So drehen Sie UIImage

Vielen Dank!

Antwort

18

Sie drehen kann UIImageView selbst mit:

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

Oder wenn Sie wirklich Bild ändern möchten, können Sie Code aus this answer verwenden, funktioniert es.

+0

ich tue, wie es sagt, aber ich habe ein Problem ... Ich dreht das Bild von der oben links, wie kann ich einstellen, dass es das Bild von der Mitte der UIImage dreht? –

+0

Sie können mit 'iv.layer.anchorPoint' spielen, aber der Standardwert ist die Mitte einer Ebene. Daher bin ich nicht sicher, warum das Bild von der oberen linken Ecke gedreht wird. – kovpas

+0

Nein, aber ich habe den Code von dem Link verwendet, den Sie mir gegeben haben. So ist es CGContextRotateCTM –

1

Eine andere Möglichkeit wäre, den UIImage mithilfe von Core Graphics erneut zu rendern. Wenn Sie den Kontext haben, verwenden Sie CGContextRotateCTM.

Mehr Infos on this Apple Doc

7

Es gibt auch imageWithCIImage:scale:orientation, wenn Sie die UIImage nicht die UIImageView

mit einer dieser Orientierungen drehen wollte:

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; 
17

So drehen Sie die Pixel können Sie mit dem Folgendes. Dadurch wird ein intermediäres UIImage mit gedrehten Metadaten erstellt und in einen Bildkontext mit transponierten Breite/Höhe-Dimensionen umgewandelt. Das sich ergebende Bild hat die Pixel gedreht wird (dh der darunterliegenden CGImage)

- (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; 
} 

Es gibt andere mögliche Werte, die für die Orientierungsparameter übergeben werden können, um 180 Grad Drehung zu erreichen, und Flips usw.

+0

Wenn das Originalbild "UIImageOrientationRight" lautet und Sie hier "UIImageOrientationLeft" festlegen, wird die resultierende Ausgabe so gequetscht, dass sie den neuen Dimensionen entspricht. – ray

3
UIImage *img = [UIImage [email protected]"aaa.png"]; 
UIImage *image = [UIImage imageWithCGImage:img.CGImage scale:1.0 orientation:UIImageOrientationRight]; 
4

mit Schnell können Sie ein Bild drehen, indem Sie Folgendes tun:

var image: UIImage = UIImage(named: "headerBack.png") 
var imageRotated: UIImage = UIImage(CGImage: image.CGImage, scale:1, orientation: UIImageOrientation.UpMirrored) 
8

Dies wird ein Bild um einen bestimmten Grad drehen.

Hinweis Dies funktioniert 2x und 3x Netzhaut als auch

- (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; 
} 
+0

Das ist großartig, aber gibt es eine Möglichkeit, dies zu tun, ohne eine UIView erstellen zu müssen? Mein Verständnis ist, dass UIView ein ziemlich schweres Objekt ist. Vielen Dank! – Mario

+0

Ich habe gefunden, dass ein CALayer anstelle einer UIView verwendet werden kann. Sie müssen die Rahmeneigenschaft festlegen, nachdem Sie den Layer erstellt haben. Sie müssen auch die Funktion CATransform3DMakeAffineTransform auf das CAAffineTransform-Objekt ("t") anwenden, um die Eigenschaft transform auf dem Layer festzulegen. Alles andere funktioniert wie es ist. Mein Verständnis ist, dass ein CALayer ein leichteres Objekt ist. – Mario

4

Hier ist die schnelle Version von @ Ryang des Objective-C-Code als Erweiterung 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 
    } 

} 

Die Verwendung image.rotate(degree) ist.

1

Dank Jason Crocker hat dies mein Problem gelöst. Nur eine kleine Korrektur, Austausch Höhe und Breite in beiden Orten und keine Verzerrung auftritt, dh

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)]; 

Mein Problem nicht durch CGContextRotateCTM gelöst werden kann, weiß ich nicht, warum. Mein Problem ist, dass ich mein Bild zu einem Server übertrage und es immer um 90 Grad angezeigt wurde. Sie können problemlos testen, ob Ihre Bilder in der Nicht-Apple-Welt funktionieren, indem Sie das Bild in ein MS Office-Programm kopieren, das Sie auf Ihrem Mac ausführen.

1

Das habe ich gemacht, als ich die Ausrichtung eines Bildes ändern wollte (um 90 Grad im Uhrzeigersinn drehen).

//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; 
} 

Das gedrehte Bild kann> 15MB groß sein (aus meiner Erfahrung). Also solltest du es komprimieren und benutzen. Andernfalls könnten Sie einen Absturz verursachen, der den Speicherdruck verursacht. Der Code, den ich für die Komprimierung verwendet habe, ist unten angegeben.

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; 
    } 
} 

Jetzt ist Ihre yourImage kann überall dort eingesetzt werden .. Glücklich Codierung ...