iPhone - CGImageCreateWithImageInRect rotating some camera roll pictures
Asked Answered
C

1

8

I am working on a pixelate application for iPhone. Because the pictures taken with the iPhone 4 camera are too big and therefore the application is working really slow when updating the pixelated picture, I am trying to create tiles of the picture first and just update the tiles not the hole picture.

When building the tiles, it works for camera roll picture taken in landscape mode (2592 x 1936 pxl) and with low resolution pictures, but not with picture taken in portrait mode (1936 x 2592 pxl).

The code for cutting the tiles from the original image looks like this:

for (i = 0; i < NrOfTilesPerHeight; i++) {
  for (j = 0; j < NrOfTilesPerWidth; j++) {
    CGRect imageRect = CGRectMake(j*TILE_WIDTH, i*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
    CGImageRef image = CGImageCreateWithImageInRect(aux.CGImage, imageRect);
    UIImage *img = [UIImage imageWithCGImage:image];
    UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
  }
}

The problem is that the image created with these tiles it is rotated to a 90 degree angle anticlockwise.

Thank you a lot, Andrei

Cruck answered 22/2, 2011 at 9:56 Comment(0)
I
7

It is because the imageOrientation isn't taken into account.

There is a similar question (Resizing UIimages pulled from the Camera also ROTATES the UIimage?) and I've modified the code a bit to work with cropping image.

Here you are:

static inline double radians (double degrees) {return degrees * M_PI/180;}

+(UIImage*)cropImage:(UIImage*)originalImage toRect:(CGRect)rect{

    CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], rect);

    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    CGContextRef bitmap = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

    if (originalImage.imageOrientation == UIImageOrientationLeft) {
        CGContextRotateCTM (bitmap, radians(90));
        CGContextTranslateCTM (bitmap, 0, -rect.size.height);

    } else if (originalImage.imageOrientation == UIImageOrientationRight) {
        CGContextRotateCTM (bitmap, radians(-90));
        CGContextTranslateCTM (bitmap, -rect.size.width, 0);

    } else if (originalImage.imageOrientation == UIImageOrientationUp) {
        // NOTHING
    } else if (originalImage.imageOrientation == UIImageOrientationDown) {
        CGContextTranslateCTM (bitmap, rect.size.width, rect.size.height);
        CGContextRotateCTM (bitmap, radians(-180.));
    }

    CGContextDrawImage(bitmap, CGRectMake(0, 0, rect.size.width, rect.size.height), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);

    UIImage *resultImage=[UIImage imageWithCGImage:ref];
    CGImageRelease(imageRef);
    CGContextRelease(bitmap);
    CGImageRelease(ref);

    return resultImage;
}
Insinuation answered 3/3, 2011 at 17:19 Comment(3)
Does this code actually work for you for images taken on an iPhone 4G camera? It has been failing (essentially cropping in random parts of the image) for the past 6 hours for me. It works fine for images from the internet (presumably because they have no rotation information).Keeton
@Andrei This code did something funky for me.. In some orientations, the x and y is switched.. So if I use a rect on a right-oriented picture, it cuts out y,x instead of x,y I think. At least, if I then later move the rect upwards on the picture and do it again, the output is moved to the right. But the orientation of the output is correct..Syllabary
Hello, on portrait mode the x and the y is switched!Implosion

© 2022 - 2024 — McMap. All rights reserved.