-2

I want to create a new UIImage from another one which is turned to 45° (at its bottom left corner, clockwise). The space around the old image would be filled white or so. In the image I uploaded, the old image would be the blue one and the new image would be the actual image I linked, including the white parts.

How I imagine the new image would look

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
user5227744
  • 127
  • 5

3 Answers3

1

Played a little bit in playground with Swift and here is my solution:

func rotateImage(image: UIImage!, var rotationDegree: CGFloat) -> UIImage {
    // 180 degress = 540 degrees, that's why we calculate modulo
    rotationDegree = rotationDegree % 360

    // If degree is negative, then calculate positive
    if rotationDegree < 0.0 {
        rotationDegree = 360 + rotationDegree
    }

    // Get image size
    let size = image.size
    let width = size.width
    let height = size.height

    // Get degree which we will use for calculation
    var calcDegree = rotationDegree
    if calcDegree > 90 {
        calcDegree = 90 - calcDegree % 90
    }

    // Calculate new size
    let newWidth = width * CGFloat(cosf(Float(calcDegree.degreesToRadians))) + height * CGFloat(sinf(Float(calcDegree.degreesToRadians)))
    let newHeight = width * CGFloat(sinf(Float(calcDegree.degreesToRadians))) + height * CGFloat(cosf(Float(calcDegree.degreesToRadians)))
    let newSize = CGSize(width: newWidth, height: newHeight)

    // Create context using new size, make it opaque, use screen scale
    UIGraphicsBeginImageContextWithOptions(newSize, true, UIScreen.mainScreen().scale)

    // Get context variable
    let context = UIGraphicsGetCurrentContext()

    // Set fill color to white (or any other)
    // If no color needed, then set opaque to false when initialize context
    CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
    CGContextFillRect(context, CGRect(origin: CGPointZero, size: newSize))

    // Rotate context and draw image
    CGContextTranslateCTM(context, newSize.width * 0.5, newSize.height * 0.5)
    CGContextRotateCTM(context, rotationDegree.degreesToRadians);
    CGContextTranslateCTM(context, newSize.width * -0.5, newSize.height * -0.5)
    image.drawAtPoint(CGPoint(x: (newSize.width - size.width) / 2.0, y: (newSize.height - size.height) / 2.0))

    // Get image from context
    let returnImage = UIGraphicsGetImageFromCurrentImageContext()

    // End graphics context
    UIGraphicsEndImageContext()

    return returnImage
}

Do not forget to include this extension:

extension CGFloat {
    var degreesToRadians : CGFloat {
        return self * CGFloat(M_PI) / 180.0
    }
}

I would recommend to go threw this answer to better understand how I calculated newSize after image is rotated.

Community
  • 1
  • 1
gontovnik
  • 690
  • 5
  • 9
0

If you just want to change the way an image is displayed, transform the image view that displays it.

If you really want a new rotated image, redraw the image in a transformed graphics context.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 2
    Example code and further explanation in my book: http://www.apeth.com/iOSBook/ch14.html#_transform http://www.apeth.com/iOSBook/ch15.html#_graphics_context_transforms – matt Aug 25 '15 at 17:32
0

If you just want to rotate the UIImageView used to display the image, you could do this:

#define DegreesToRadians(x) ((x) * M_PI / 180.0) //put this at the top of your file
imageView.transform = CGAffineTransformMakeRotation(DegreesToRadians(45));

But if you want to rotate the actual image, do something like this:

- (UIImage *)image:(UIImage *)image rotatedByDegrees:(CGFloat)degrees
{
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    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, DegreesToRadians(degrees));

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

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

Above code adapted from this answer by The Lion https://stackoverflow.com/a/11667808/1757960

Community
  • 1
  • 1
Jota
  • 149
  • 3
  • 9