webentwicklung-frage-antwort-db.com.de

Wie drehe ich ein UIImage um 90 Grad?

Ich habe ein UIImage, das UIImageOrientationUp (Hochformat) ist, das ich gegen den Uhrzeigersinn um 90 Grad drehen möchte (ins Querformat). Ich möchte kein CGAffineTransform verwenden. Ich möchte, dass die Pixel von UIImage tatsächlich die Position verschieben. Ich verwende einen Codeblock (siehe unten), der ursprünglich dazu gedacht war, die Größe eines UIImage zu ändern. Ich habe eine Zielgröße als die aktuelle Größe von UIImage festgelegt, aber es wird eine Fehlermeldung angezeigt:

(Fehler): CGBitmapContextCreate: ungültige Datenbytes/Zeile: sollte mindestens 1708 für 8 ganzzahlige Bits/Komponente, 3 Komponenten, kCGImageAlphaPremultipliedLast sein.

(Ich erhalte keine Fehlermeldung, wenn ich eine KLEINERE Größe als Zielgröße angeben möchte.) Wie kann ich mein UIImage 90 Grad im Uhrzeigersinn drehen, indem ich nur die wichtigsten Grafikfunktionen verwende und dabei die aktuelle Größe behalte?

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

    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, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

    } else {


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

    }       


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

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

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

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

    CGContextRelease(bitmap);
    CGImageRelease(ref);

    return newImage; 
}
173
RexOnRoids

Was ist mit so etwas wie:

static inline double radians (double degrees) {return degrees * M_PI/180;}
UIImage* rotate(UIImage* src, UIImageOrientation orientation)
{
    UIGraphicsBeginImageContext(src.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orientation == UIImageOrientationRight) {
        CGContextRotateCTM (context, radians(90));
    } else if (orientation == UIImageOrientationLeft) {
        CGContextRotateCTM (context, radians(-90));
    } else if (orientation == UIImageOrientationDown) {
        // NOTHING
    } else if (orientation == UIImageOrientationUp) {
        CGContextRotateCTM (context, radians(90));
    }

    [src drawAtPoint:CGPointMake(0, 0)];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
87
fbrereto

Ich glaube, der einfachste Weg (und Thread sicher auch) ist zu tun:

//assume that the image is loaded in landscape mode from disk
UIImage * landscapeImage = [UIImage imageNamed:imgname];
UIImage * portraitImage = [[UIImage alloc] initWithCGImage: landscapeImage.CGImage
                                                     scale: 1.0
                                               orientation: UIImageOrientationRight];

Hinweis: Wie Brainware sagte, ändert dies nur die Ausrichtungsdaten des Bildes - die Pixeldaten bleiben unberührt. Für einige Anwendungen reicht dies möglicherweise nicht aus.

Oder in Swift:

let portraitImage  : UIImage = UIImage(CGImage: landscapeImage.CGImage ,
            scale: 1.0 ,
            orientation: UIImageOrientation.Right)
409
Peter Sarnowski

Schauen Sie sich den einfachen und fantastischen Code von Hardy Macia an: Schneiden-Skalieren-und-Drehen-von-Bildern

Ruf einfach an

UIImage *rotatedImage = [originalImage imageRotatedByDegrees:90.0];

Vielen Dank Hardy Macia!

Header:

  • (UIImage *) imageAtRect: (CGRect) rect;
  • (UIImage *) imageByScalingProportionallyToMinimumSize: (CGSize) targetSize;
  • (UIImage *) imageByScalingProportionallyToSize: (CGSize) targetSize;
  • (UIImage *) imageByScalingToSize: (CGSize) targetSize;
  • (UIImage *) imageRotatedByRadians: (CGFloat) radians;
  • (UIImage *) imageRotatedByDegrees: (CGFloat) Grad;

Da der Link möglicherweise nicht mehr funktioniert, ist hier der vollständige Code

//
//  UIImage-Extensions.h
//
//  Created by Hardy Macia on 7/1/09.
//  Copyright 2009 Catamount Software. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface UIImage (CS_Extensions)
- (UIImage *)imageAtRect:(CGRect)rect;
- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize;
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
- (UIImage *)imageByScalingToSize:(CGSize)targetSize;
- (UIImage *)imageRotatedByRadians:(CGFloat)radians;
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;

@end;

//
//  UIImage-Extensions.m
//
//  Created by Hardy Macia on 7/1/09.
//  Copyright 2009 Catamount Software. All rights reserved.
//

#import "UIImage-Extensions.h"

CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};

@implementation UIImage (CS_Extensions)

-(UIImage *)imageAtRect:(CGRect)rect
{

   CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
   UIImage* subImage = [UIImage imageWithCGImage: imageRef];
   CGImageRelease(imageRef);

   return subImage;

}

- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize {

   UIImage *sourceImage = self;
   UIImage *newImage = nil;

   CGSize imageSize = sourceImage.size;
   CGFloat width = imageSize.width;
   CGFloat height = imageSize.height;

   CGFloat targetWidth = targetSize.width;
   CGFloat targetHeight = targetSize.height;

   CGFloat scaleFactor = 0.0;
   CGFloat scaledWidth = targetWidth;
   CGFloat scaledHeight = targetHeight;

   CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

   if (CGSizeEqualToSize(imageSize, targetSize) == NO) {

      CGFloat widthFactor = targetWidth / width;
      CGFloat heightFactor = targetHeight / height;

      if (widthFactor > heightFactor) 
         scaleFactor = widthFactor;
      else
         scaleFactor = heightFactor;

      scaledWidth  = width * scaleFactor;
      scaledHeight = height * scaleFactor;

      // center the image

      if (widthFactor > heightFactor) {
         thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
      } else if (widthFactor < heightFactor) {
         thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
      }
   }


   // this is actually the interesting part:

   UIGraphicsBeginImageContext(targetSize);

   CGRect thumbnailRect = CGRectZero;
   thumbnailRect.Origin = thumbnailPoint;
   thumbnailRect.size.width  = scaledWidth;
   thumbnailRect.size.height = scaledHeight;

   [sourceImage drawInRect:thumbnailRect];

   newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   if(newImage == nil) NSLog(@"could not scale image");


   return newImage ;
}


- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {

   UIImage *sourceImage = self;
   UIImage *newImage = nil;

   CGSize imageSize = sourceImage.size;
   CGFloat width = imageSize.width;
   CGFloat height = imageSize.height;

   CGFloat targetWidth = targetSize.width;
   CGFloat targetHeight = targetSize.height;

   CGFloat scaleFactor = 0.0;
   CGFloat scaledWidth = targetWidth;
   CGFloat scaledHeight = targetHeight;

   CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

   if (CGSizeEqualToSize(imageSize, targetSize) == NO) {

      CGFloat widthFactor = targetWidth / width;
      CGFloat heightFactor = targetHeight / height;

      if (widthFactor < heightFactor) 
         scaleFactor = widthFactor;
      else
         scaleFactor = heightFactor;

      scaledWidth  = width * scaleFactor;
      scaledHeight = height * scaleFactor;

      // center the image

      if (widthFactor < heightFactor) {
         thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
      } else if (widthFactor > heightFactor) {
         thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
      }
   }


   // this is actually the interesting part:

   UIGraphicsBeginImageContext(targetSize);

   CGRect thumbnailRect = CGRectZero;
   thumbnailRect.Origin = thumbnailPoint;
   thumbnailRect.size.width  = scaledWidth;
   thumbnailRect.size.height = scaledHeight;

   [sourceImage drawInRect:thumbnailRect];

   newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   if(newImage == nil) NSLog(@"could not scale image");


   return newImage ;
}


- (UIImage *)imageByScalingToSize:(CGSize)targetSize {

   UIImage *sourceImage = self;
   UIImage *newImage = nil;

   //   CGSize imageSize = sourceImage.size;
   //   CGFloat width = imageSize.width;
   //   CGFloat height = imageSize.height;

   CGFloat targetWidth = targetSize.width;
   CGFloat targetHeight = targetSize.height;

   //   CGFloat scaleFactor = 0.0;
   CGFloat scaledWidth = targetWidth;
   CGFloat scaledHeight = targetHeight;

   CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

   // this is actually the interesting part:

   UIGraphicsBeginImageContext(targetSize);

   CGRect thumbnailRect = CGRectZero;
   thumbnailRect.Origin = thumbnailPoint;
   thumbnailRect.size.width  = scaledWidth;
   thumbnailRect.size.height = scaledHeight;

   [sourceImage drawInRect:thumbnailRect];

   newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   if(newImage == nil) NSLog(@"could not scale image");


   return newImage ;
}


- (UIImage *)imageRotatedByRadians:(CGFloat)radians
{
   return [self imageRotatedByDegrees:RadiansToDegrees(radians)];
}

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees 
{   
   // calculate the size of the rotated view's containing box for our drawing space
   UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
   CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
   rotatedViewBox.transform = t;
   CGSize rotatedSize = rotatedViewBox.frame.size;
   [rotatedViewBox release];

   // Create the bitmap context
   UIGraphicsBeginImageContext(rotatedSize);
   CGContextRef bitmap = UIGraphicsGetCurrentContext();

   // Move the Origin to the middle of the image so we will rotate and scale around the center.
   CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

   //   // Rotate the image context
   CGContextRotateCTM(bitmap, DegreesToRadians(degrees));

   // Now, draw the rotated/scaled image into the context
   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;

}

@end;
108
Ben Groot

So seltsam das auch scheint, der folgende Code hat das Problem für mich gelöst:

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

    return newImage;
}
31
Stavash

Eine thread-sichere Rotationsfunktion ist die folgende (es funktioniert viel besser):

-(UIImage*)imageByRotatingImage:(UIImage*)initImage fromImageOrientation:(UIImageOrientation)orientation
{
CGImageRef imgRef = initImage.CGImage;

CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);

CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = orientation;
switch(orient) {

    case UIImageOrientationUp: //EXIF = 1
        return initImage;
        break;

    case UIImageOrientationUpMirrored: //EXIF = 2
        transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        break;

    case UIImageOrientationDown: //EXIF = 3
        transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
        transform = CGAffineTransformRotate(transform, M_PI);
        break;

    case UIImageOrientationDownMirrored: //EXIF = 4
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
        transform = CGAffineTransformScale(transform, 1.0, -1.0);
        break;

    case UIImageOrientationLeftMirrored: //EXIF = 5
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
        break;

    case UIImageOrientationLeft: //EXIF = 6
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
        transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
        break;

    case UIImageOrientationRightMirrored: //EXIF = 7
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeScale(-1.0, 1.0);
        transform = CGAffineTransformRotate(transform, M_PI / 2.0);
        break;

    case UIImageOrientationRight: //EXIF = 8
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
        transform = CGAffineTransformRotate(transform, M_PI / 2.0);
        break;

    default:
        [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

}
// Create the bitmap context
CGContextRef    context = NULL;
void *          bitmapData;
int             bitmapByteCount;
int             bitmapBytesPerRow;

// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow   = (bounds.size.width * 4);
bitmapByteCount     = (bitmapBytesPerRow * bounds.size.height);
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
    return nil;
}

// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
CGColorSpaceRef colorspace = CGImageGetColorSpace(imgRef);
context = CGBitmapContextCreate (bitmapData,bounds.size.width,bounds.size.height,8,bitmapBytesPerRow,
                                 colorspace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);

if (context == NULL)
    // error creating context
    return nil;

CGContextScaleCTM(context, -1.0, -1.0);
CGContextTranslateCTM(context, -bounds.size.width, -bounds.size.height);

CGContextConcatCTM(context, transform);

// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(context, CGRectMake(0,0,width, height), imgRef);

CGImageRef imgRef2 = CGBitmapContextCreateImage(context);
CGContextRelease(context);
free(bitmapData);
UIImage * image = [UIImage imageWithCGImage:imgRef2 scale:initImage.scale orientation:UIImageOrientationUp];
CGImageRelease(imgRef2);
return image;
}
29
thewormsterror

Ich hatte Probleme mit all dem, einschließlich der genehmigten Antwort. Ich habe Hardys Kategorie wieder in eine Methode umgewandelt, da ich nur ein Bild drehen wollte. Hier ist der Code und die Verwendung:

- (UIImage *)imageRotatedByDegrees:(UIImage*)oldImage deg:(CGFloat)degrees{
// calculate the size of the rotated view's containing box for our drawing space
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,oldImage.size.width, oldImage.size.height)];
CGAffineTransform t = CGAffineTransformMakeRotation(degrees * M_PI / 180);
rotatedViewBox.transform = t;
CGSize rotatedSize = rotatedViewBox.frame.size;
// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef bitmap = UIGraphicsGetCurrentContext();

// Move the Origin to the middle of the image so we will rotate and scale around the center.
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

//   // Rotate the image context
CGContextRotateCTM(bitmap, (degrees * M_PI / 180));

// Now, draw the rotated/scaled image into the context
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextDrawImage(bitmap, CGRectMake(-oldImage.size.width / 2, -oldImage.size.height / 2, oldImage.size.width, oldImage.size.height), [oldImage CGImage]);

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

Und die Verwendung:

UIImage *image2 = [self imageRotatedByDegrees:image deg:90];

Vielen Dank Hardy!

17
Jim True

Bild um 90 Grad drehen (im/gegen den Uhrzeigersinn)

Funktionsaufruf -

 UIImage *rotatedImage = [self rotateImage:originalImage clockwise:YES];

Implementierung:

- (UIImage*)rotateImage:(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;
  }
15
nilam_mande

Hier ist eine Swift Erweiterung zu UIImage, die das Bild um einen beliebigen Winkel dreht. Verwenden Sie diese wie folgt: let rotatedImage = image.rotated(byDegrees: degree). Ich habe den Objective-C-Code in einem der anderen verwendet antwortet und entfernt ein paar fehlerhafte Zeilen (gedrehtes Box-Zeug) und verwandelt es in eine Erweiterung für UIImage.

extension UIImage {

func rotate(byDegrees degree: Double) -> UIImage {
    let radians = CGFloat(degree*M_PI)/180.0 as CGFloat
    let rotatedSize = self.size
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
    let 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 );
    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    return newImage
}
}
5
RawMean

Einfach. Ändern Sie einfach die Bildausrichtungsflagge.

UIImage *oldImage = [UIImage imageNamed:@"whatever.jpg"];
UIImageOrientation newOrientation;
switch (oldImage.imageOrientation) {
    case UIImageOrientationUp:
        newOrientation = UIImageOrientationLandscapeLeft;
        break;
    case UIImageOrientationLandscapeLeft:
        newOrientation = UIImageOrientationDown;
        break;
    case UIImageOrientationDown:
        newOrientation = UIImageOrientationLandscapeRight;
        break;
    case UIImageOrientationLandscapeRight:
        newOrientation = UIImageOrientationUp;
        break;
    // you can also handle mirrored orientations similarly ...
}
UIImage *rotatedImage = [UIImage imageWithCGImage:oldImage.CGImage scale:1.0f orientation:newOrientation];
5
Adam Freeman

Swift 3 UIImage Erweiterung:

func fixOrientation() -> UIImage {

    // No-op if the orientation is already correct
    if ( self.imageOrientation == .up ) {
        return self;
    }

    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    var transform: CGAffineTransform = .identity

    if ( self.imageOrientation == .down || self.imageOrientation == .downMirrored ) {
        transform = transform.translatedBy(x: self.size.width, y: self.size.height)
        transform = transform.rotated(by: .pi)
    }

    if ( self.imageOrientation == .left || self.imageOrientation == .leftMirrored ) {
        transform = transform.translatedBy(x: self.size.width, y: 0)
        transform = transform.rotated(by: .pi/2)
    }

    if ( self.imageOrientation == .right || self.imageOrientation == .rightMirrored ) {
        transform = transform.translatedBy(x: 0, y: self.size.height);
        transform = transform.rotated(by: -.pi/2);
    }

    if ( self.imageOrientation == .upMirrored || self.imageOrientation == .downMirrored ) {
        transform = transform.translatedBy(x: self.size.width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)
    }

    if ( self.imageOrientation == .leftMirrored || self.imageOrientation == .rightMirrored ) {
        transform = transform.translatedBy(x: self.size.height, y: 0);
        transform = transform.scaledBy(x: -1, y: 1);
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    let ctx: CGContext = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height),
                                   bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0,
                                   space: self.cgImage!.colorSpace!,
                                   bitmapInfo: self.cgImage!.bitmapInfo.rawValue)!;

    ctx.concatenate(transform)

    if ( self.imageOrientation == .left ||
        self.imageOrientation == .leftMirrored ||
        self.imageOrientation == .right ||
        self.imageOrientation == .rightMirrored ) {
        ctx.draw(self.cgImage!, in: CGRect(x: 0.0,y: 0.0,width: self.size.height,height: self.size.width))
    } else {
        ctx.draw(self.cgImage!, in: CGRect(x: 0.0,y: 0.0,width: self.size.width,height: self.size.height))
    }

    // And now we just create a new UIImage from the drawing context and return it
    return UIImage(cgImage: ctx.makeImage()!)
}
5
protspace

Wenn Sie eine Fotodrehschaltfläche hinzufügen möchten, mit der das Foto in 90-Grad-Schritten weiter gedreht wird, können Sie loslegen. (finalImage ist ein UIImage, das bereits an anderer Stelle erstellt wurde.)

- (void)rotatePhoto {
    UIImage *rotatedImage;

    if (finalImage.imageOrientation == UIImageOrientationRight)
        rotatedImage = [[UIImage alloc] initWithCGImage: finalImage.CGImage
                                              scale: 1.0
                                        orientation: UIImageOrientationDown];
    else if (finalImage.imageOrientation == UIImageOrientationDown)
        rotatedImage = [[UIImage alloc] initWithCGImage: finalImage.CGImage
                                              scale: 1.0
                                        orientation: UIImageOrientationLeft];
    else if (finalImage.imageOrientation == UIImageOrientationLeft)
        rotatedImage = [[UIImage alloc] initWithCGImage: finalImage.CGImage
                                              scale: 1.0
                                        orientation: UIImageOrientationUp];
    else
        rotatedImage = [[UIImage alloc] initWithCGImage: finalImage.CGImage
                                                     scale: 1.0
                                               orientation: UIImageOrientationRight];
    finalImage = rotatedImage;
}
5
bmueller

Ich probiere diesen Code aus, er funktioniert und habe von http://www.catamount.com/blog/1015/uiimage-extensions-for-cutting-scaling-and-rotating-uiimages/

+ (UIImage *)rotateImage:(UIImage*)src byRadian:(CGFloat)radian
{
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, src.size.width, src.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(radian);
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the Origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    //   // Rotate the image context
    CGContextRotateCTM(bitmap, radian);

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-src.size.width / 2, -src.size.height / 2, src.size.width, src.size.height), [src CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
2
lbsweek

Kleinere Änderungen an den anderen Antworten, die auf Hardy Macias Code basieren. Es ist nicht erforderlich, ein ganzes UIView -Objekt zu erstellen, um lediglich das Begrenzungsrechteck des gedrehten Bildes zu berechnen. Wenden Sie einfach eine Drehungstransformation mit CGRectApplyAffineTransform auf das Bildrechteck an.

static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}
static CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;}


- (CGSize)rotatedImageSize:(CGFloat)degrees
{
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    CGRect originalImageRect = CGRectMake(0, 0, self.size.width, self.size.height);
    CGRect rotatedImageRect = CGRectApplyAffineTransform(originalImageRect, t);
    CGSize rotatedSize = rotatedImageRect.size;

    return rotatedSize;
}

- (UIImage*)imageRotatedByDegrees:(CGFloat)degrees
{
    // calculate the size of the rotated view's containing box for our drawing space
    CGSize rotatedSize = [self rotatedImageSize:degrees];

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the Origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    //   // Rotate the image context
    CGContextRotateCTM(bitmap, DegreesToRadians(degrees));

    // Now, draw the rotated/scaled image into the context
    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;
}
2
user2067021

Swift 4.2-Version von RawMeans Antwort :

extension UIImage {

func rotated(byDegrees degree: Double) -> UIImage {
    let radians = CGFloat(degree * .pi) / 180.0 as CGFloat
    let rotatedSize = self.size
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
    let bitmap = UIGraphicsGetCurrentContext()
    bitmap?.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
    bitmap?.rotate(by: radians)
    bitmap?.scaleBy(x: 1.0, y: -1.0)
    bitmap?.draw(
        self.cgImage!,
        in: CGRect.init(x: -self.size.width / 2, y: -self.size.height / 2 , width: self.size.width, height: self.size.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext() // this is needed
    return newImage!
}

}
1
Brian Hong

Ich mag die schlichte Eleganz der Antwort von Peter Sarnowski, Aber es kann Probleme verursachen, wenn Sie sich nicht auf EXIF Metadaten und dergleichen verlassen können. In Situationen, in denen Sie die eigentlichen Bilddaten drehen müssen würde ich Folgendes empfehlen:

- (UIImage *)rotateImage:(UIImage *) img
{
    CGSize imgSize = [img size];
    UIGraphicsBeginImageContext(imgSize);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextRotateCTM(context, M_PI_2);
    CGContextTranslateCTM(context, 0, -640);
    [img drawInRect:CGRectMake(0, 0, imgSize.height, imgSize.width)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

Der obige Code nimmt ein Bild mit der Ausrichtung Landscape (kann mich nicht erinnern, ob es Landscape Left Oder Landscape Right Ist) und dreht es in Portrait. Es ist ein Beispiel, das an Ihre Bedürfnisse angepasst werden kann.

Die wichtigsten Argumente, mit denen Sie spielen müssten, sind CGContextRotateCTM(context, M_PI_2), in dem Sie entscheiden, um wie viel Sie drehen möchten, aber dann müssen Sie sicherstellen, dass das Bild mit CGContextTranslateCTM(context, 0, -640) immer noch auf dem Bildschirm gezeichnet wird. . Dieser letzte Teil ist sehr wichtig, um sicherzustellen, dass Sie das Bild und nicht einen leeren Bildschirm sehen.

Weitere Informationen finden Sie in Quelle .

0
Eric Brotto
0
P i

Für Swift: Hier ist eine einfache Erweiterung von UIImage:

//ImageRotation.Swift

import UIKit

extension UIImage {  
    public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage {
        let radiansToDegrees: (CGFloat) -> CGFloat = {
            return $0 * (180.0 / CGFloat(M_PI))
        }
        let degreesToRadians: (CGFloat) -> CGFloat = {
            return $0 / 180.0 * CGFloat(M_PI)
        }

        // calculate the size of the rotated view's containing box for our drawing space
        let rotatedViewBox = UIView(frame: CGRect(Origin: CGPointZero, size: size))
        let t = CGAffineTransformMakeRotation(degreesToRadians(degrees));
        rotatedViewBox.transform = t
        let rotatedSize = rotatedViewBox.frame.size

        // Create the bitmap context
        UIGraphicsBeginImageContext(rotatedSize)
        let bitmap = UIGraphicsGetCurrentContext()

        // Move the Origin to the middle of the image so we will rotate and scale around the center.
        CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0);

        //   // Rotate the image context
        CGContextRotateCTM(bitmap, degreesToRadians(degrees));

        // Now, draw the rotated/scaled image into the context
        var yFlip: CGFloat

        if(flip){
            yFlip = CGFloat(-1.0)
        } else {
            yFlip = CGFloat(1.0)
        }

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

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }
}

( Quelle )

Verwenden Sie es mit:

rotatedPhoto = rotatedPhoto?.imageRotatedByDegrees(90, flip: false) 

Ersteres dreht ein Bild und kippt es, wenn die Kippfunktion auf true gesetzt ist.

0
confile

resize-a-uiimage-the-right-way erklärt einige der Probleme, die viele Codebeispiele dafür haben, und enthält einige Codefragmente, die beim Umgang mit UIImages helfen - der privaten Hilfsmethode in UIImage + resize .m akzeptiert eine Transformation, um Rotation zuzulassen. Sie müssen diese also nur als öffentliche Schnittstelle verfügbar machen.

// Returns a copy of the image that has been transformed using the given affine transform and scaled to the new size
// The new image's orientation will be UIImageOrientationUp, regardless of the current image's orientation
// If the new size is not integral, it will be rounded up
- (UIImage *)resizedImage:(CGSize)newSize
                transform:(CGAffineTransform)transform
           drawTransposed:(BOOL)transpose
     interpolationQuality:(CGInterpolationQuality)quality {
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
    CGImageRef imageRef = self.CGImage;

    // Build a context that's the same dimensions as the new size
    CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                                newRect.size.width,
                                                newRect.size.height,
                                                CGImageGetBitsPerComponent(imageRef),
                                                0,
                                                CGImageGetColorSpace(imageRef),
                                                CGImageGetBitmapInfo(imageRef));

    // Rotate and/or flip the image if required by its orientation
    CGContextConcatCTM(bitmap, transform);

    // Set the quality level to use when rescaling
    CGContextSetInterpolationQuality(bitmap, quality);

    // Draw into the context; this scales the image
    CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);

    // Get the resized image from the context and a UIImage
    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    // Clean up
    CGContextRelease(bitmap);
    CGImageRelease(newImageRef);

    return newImage;
}

Dies ist die Lizenz aus dieser Datei:

// Created by Trevor Harmon on 8/5/09.
// Free for personal or commercial use, with or without modification.
// No warranty is expressed or implied.
0
JosephH

Es gibt eine äußerst effiziente UIImage-Kategorie namens NYXImagesKit. Es verwendet vDSP, CoreImage und vImage, um so schnell wie möglich zu sein. Es hat eine UIImage + Rotating Kategorie, die meinen Tag gerettet hat :)

https://github.com/Nyx0uf/NYXImagesKit

0
Ruben Marin