Resizing UIimages pulled from the Camera also ROTATES the UIimage? - iphone

I am getting UIimages from the camera and assigning them to UIImageViews to be displayed. When I do this the camera gives me a 1200 x 1600 pixel image which I then assign to a UIImageView in my Application. The image is displayed as expected in the image view under this condition. However, when I attempt to RESIZE the retrieved UIImage before assigning it to the UIImageView, the image is resizing as expected but there IS a problem in that somewhere (in the RESIZING code?) my UIImage is getting ROTATED... As a result, when I assign the resized UIImage to a UIImageView the image is rotated 90 degrees and appears stretched as the aspect ratio (1200 x 1600 pixels) was unchanged...
I am using this to get a UIImage from the Camera:
- (void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
myImg = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
myResizedImg = [self resizeImage:myImg width:400 height:533];
[myImageView setImage:myResizedImg];
}
I am using this to resize it:
-(UIImage *)resizeImage:(UIImage *)anImage width:(int)width height:(int)height
{
CGImageRef imageRef = [anImage CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return result;
}
QUESTION: How do I RESIZE a UIImage pulled from the Camera WITHOUT rotating the pixels?

The reason your code doesn't work is because the imageOrientation on the code that you have is not being taken into account. Specifically, if the imageOrientation is right/left, then you need to both rotate the image and swap width/height. Here is some code to do this:
-(UIImage*)imageByScalingToSize:(CGSize)targetSize
{
UIImage* sourceImage = self;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
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, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
} else {
bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
}
if (sourceImage.imageOrientation == UIImageOrientationLeft) {
CGContextRotateCTM (bitmap, radians(90));
CGContextTranslateCTM (bitmap, 0, -targetHeight);
} else if (sourceImage.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM (bitmap, radians(-90));
CGContextTranslateCTM (bitmap, -targetWidth, 0);
} else if (sourceImage.imageOrientation == UIImageOrientationUp) {
// NOTHING
} else if (sourceImage.imageOrientation == UIImageOrientationDown) {
CGContextTranslateCTM (bitmap, targetWidth, targetHeight);
CGContextRotateCTM (bitmap, radians(-180.));
}
CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage* newImage = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return newImage;
}
This will resize your image and rotate it to the correct orientation. If you need the definition for radians, it is:
static inline double radians (double degrees) {return degrees * M_PI/180;}
The answer Daniel gave is also correct, but it suffers from the problem that it is not thread-safe, since you're using UIGraphicsBeginImageContext(). Since the above code only uses CG functions, you're all set. I also have a similar function to resize and do proper aspect fill on images - let me know if that's what you're looking for.
Note: I got the original function from this post, and did some modifications to make it work on JPEGs.

I had this problem too with some of the code out there, i found this code that works, check it out, let me know what you find
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

Swift 3
I add this to didFinishPickingMediaWithInfo method and then use image without worrying for its rotation.
var image = info[UIImagePickerControllerOriginalImage] as! UIImage
if (image.imageOrientation != .up) {
UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
}

If you want to make a square image from a rectangle image (no matter horizontal or vertical) by cropping it by width or height in both sides, use my code. The difference is that I don't stretch, but I crop. I made it from the top code by modification:
//Cropping _image to fit it to the square by height or width
CGFloat a = _image.size.height;
CGFloat b = _image.size.width;
CGRect cropRect;
if (!(a==b)) {
if (a<b) {
cropRect = CGRectMake((b-a)/2.0, 0, a, a);
b = a;
}
else if (b<a) {
cropRect = CGRectMake(0, (a-b)/2.0, b, b);
a = b;
}
CGImageRef imageRef = CGImageCreateWithImageInRect([_image CGImage], cropRect);
UIImage* sourceImage = _image;
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
CGContextRef bitmap;
if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
} else {
bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
}
if (sourceImage.imageOrientation == UIImageOrientationLeft) {
CGContextRotateCTM (bitmap, radians(90));
CGContextTranslateCTM (bitmap, 0, -a);
} else if (sourceImage.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM (bitmap, radians(-90));
CGContextTranslateCTM (bitmap, -a, 0);
} else if (sourceImage.imageOrientation == UIImageOrientationUp) {
// NOTHING
} else if (sourceImage.imageOrientation == UIImageOrientationDown) {
CGContextTranslateCTM (bitmap, a, a);
CGContextRotateCTM (bitmap, radians(-180.));
}
CGContextDrawImage(bitmap, CGRectMake(0, 0, a, a), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
_image = [UIImage imageWithCGImage:ref];
CGImageRelease(imageRef);
}

Related

App Crash due to Receive memory warning in CGContextDrawImage?

my app Crash due to Receive memory Warning.when i run app with instruments then i get the following leak memory issue .
here is my full code of this method.
- (UIImage *)resizeImage:(UIImage *)orignalImage newWidth:(int)width newHeight:(int)height bgColor:(UIColor *)bgColor
{
CGRect newRect;
if((orignalImage.size.width>width) || (orignalImage.size.height>height))
{
float newWidth,newHeight;
if(orignalImage.size.width>orignalImage.size.height)
{
newWidth=width;
newHeight=(height*orignalImage.size.height)/orignalImage.size.width;
}
else if(orignalImage.size.height>orignalImage.size.width)
{
newWidth=(width*orignalImage.size.width)/orignalImage.size.height;
newHeight=height;
}
else
{
newWidth=width;
newHeight=height;
}
newRect.origin.x=(width-newWidth)/2;
newRect.origin.y=(height-newHeight)/2;
newRect.size.width=newWidth;
newRect.size.height=newHeight;
}
else
{
newRect.origin.x=(width-(orignalImage.size.width))/2;
newRect.origin.y=(height-(orignalImage.size.height))/2;
newRect.size.width=orignalImage.size.width;
newRect.size.height=orignalImage.size.height;
}
CGImageRef imageRef = [orignalImage CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
//if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);
CGContextSetFillColorWithColor(bitmap, bgColor.CGColor);
CGContextFillRect(bitmap, CGRectMake(0, 0, width, height));
CGContextDrawImage(bitmap, newRect, imageRef);
CGImageRef newImgRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImg = [UIImage imageWithCGImage:newImgRef];
CGContextRelease(bitmap);
CGImageRelease(newImgRef);
return newImg;
}
Some one can suggest me what mistake in my code.any help will be apprericated thanks.

Rotation of UIImage in iPhone

I have a problem
When I get an image from iPhone camera. i can get that in all orientations Like LeftLandscape, RightLandscape, Portrait and portrait upside down.
Now how can I rotate the image fetched from Camera Delegates to only one orientation i.e. Only in Portrait OR Landscape Right
Can anybody HElp ?
Try this...
CGSize size = sizeOfImage;
UIGraphicsBeginImageContext(size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextRotateCTM(ctx, angleInRadians);
CGContextDrawImage(UIGraphicsGetCurrentContext(),
CGRectMake(0,0,size.width, size.height),
image);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
Also refer this link...it will help you out...
http://www.platinumball.net/blog/2009/03/30/iphone-uiimage-rotation-and-mirroring/
NYXImagesKit: Handy UIImage Categories
By Benjamin Godard
This is a handy set of categories on UIImage for rotating, resizing, filtering, enhancing and more, in an efficient and easy-to-use manner. Might be useful in some of your apps!
Try this.It will be helpful
-(UIImage *)resizeImage:(UIImage *)image {
CGImageRef imageRef = [image CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
CGColorSpaceRef colorSpaceInfo = CGColorSpaceCreateDeviceRGB();
if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
int width, height;
width = 640;//[image size].width;
height = 640;//[image size].height;
CGContextRef bitmap;
if (image.imageOrientation == UIImageOrientationUp | image.imageOrientation == UIImageOrientationDown) {
bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
} else {
bitmap = CGBitmapContextCreate(NULL, height, width, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
}
if (image.imageOrientation == UIImageOrientationLeft) {
NSLog(#"image orientation left");
CGContextRotateCTM (bitmap, radians(90));
CGContextTranslateCTM (bitmap, 0, -height);
} else if (image.imageOrientation == UIImageOrientationRight) {
NSLog(#"image orientation right");
CGContextRotateCTM (bitmap, radians(-90));
CGContextTranslateCTM (bitmap, -width, 0);
} else if (image.imageOrientation == UIImageOrientationUp) {
NSLog(#"image orientation up");
} else if (image.imageOrientation == UIImageOrientationDown) {
NSLog(#"image orientation down");
CGContextTranslateCTM (bitmap, width,height);
CGContextRotateCTM (bitmap, radians(-180.));
}
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return result;
}

Large PNG Images in iPhone App Dev

I have a question about the png images I am using in my iPhone app. I have a lot of large images for different views, they are compressed but I was wondering if that would slow down the application at all. Like in initial loading time and loading different views Basically I need to know how to make the app smaller in size and faster by just adjusting the images? Or if it is even worth it to mess with that?
I HAVE done research on this topic but I haven't found any viable solutions besides compressing the images.
Any help is much appreciated?
Hope, this helps !!!
http://www.iphonedevsdk.com/forum/iphone-sdk-development/7307-resizing-photo-new-uiimage.html
-(UIImage *)resizeImage:(UIImage *)image {
CGImageRef imageRef = [image CGImage];
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
CGColorSpaceRef colorSpaceInfo = CGColorSpaceCreateDeviceRGB();
if (alphaInfo == kCGImageAlphaNone)
alphaInfo = kCGImageAlphaNoneSkipLast;
int width, height;
width = 640;
height = 480;
CGContextRef bitmap;
if (image.imageOrientation == UIImageOrientationUp | image.imageOrientation == UIImageOrientationDown) {
bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
} else {
bitmap = CGBitmapContextCreate(NULL, height, width, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
}
if (image.imageOrientation == UIImageOrientationLeft) {
NSLog(#"image orientation left");
CGContextRotateCTM (bitmap, radians(90));
CGContextTranslateCTM (bitmap, 0, -height);
} else if (image.imageOrientation == UIImageOrientationRight) {
NSLog(#"image orientation right");
CGContextRotateCTM (bitmap, radians(-90));
CGContextTranslateCTM (bitmap, -width, 0);
} else if (image.imageOrientation == UIImageOrientationUp) {
NSLog(#"image orientation up");
} else if (image.imageOrientation == UIImageOrientationDown) {
NSLog(#"image orientation down");
CGContextTranslateCTM (bitmap, width,height);
CGContextRotateCTM (bitmap, radians(-180.));
}
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return result;
}
When you use your app, do you notice slow loading times? If not then don't bother messing with the images, the gains will be minimal if at all.
If you are having problems with loading times on your app then don't assume it is the PNGs. Use the tools provided and profile your app to find out what the slow parts are and start from there. Never assume you know what the cause of slow code is.

iPhone - CGImageCreateWithImageInRect rotating some camera roll pictures

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

How to change the size of the crop rect when using UIImagePickerController

I need to change the size of the cropping rect when using UIImagePickerController. In my case, I need the user to select images that are 320x385 but the crop rect currently only allows 320x320 (when allow editing is on).
Any ideas?
I have done a similar project. You have to use an image controller. Above your image controller you have to add another image controller (just because this is your crop area)
aboveImageController's unfilled/empty part is where you will take. (so you should have an image with 320x480 sized and 320x385 empty in it.)
UIImage *image=theimageView.image;
CGSize newSize;
newSize.width=320;
newSize.height=385;
UIGraphicsBeginImageContext(newSize);
//x=0 (because widhth : 320) y=0 (aboveImageController's empty part's start)
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = CGImageCreateWithImageInRect([newImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
The dictionary in the delegate method returns all that:
NSString *const UIImagePickerControllerMediaType;
NSString *const UIImagePickerControllerOriginalImage;
NSString *const UIImagePickerControllerEditedImage;
NSString *const UIImagePickerControllerCropRect;
NSString *const UIImagePickerControllerMediaURL;
NSString *const UIImagePickerControllerReferenceURL;
NSString *const UIImagePickerControllerMediaMetadata;
I assume, you've been using the EditedImage which is pretty much useless ... maybe for some thumbnails ... anyway, the info dictionary contains CropRect data, only thing you have to do is to recalculate the sizes and crop the OriginalImage yourself, using for example this:
UIImage: Resize, then Crop
I haven't tested, this is just theory :) ... but in theory, this should work :D
After getting image from image picker and give crop functionality as different module. So user can select the part of image which one they want to crop.
You can use this
UIImage *image1 = [self resizeImage:image width:320 height:385];
-(UIImage *)resizeImage:(UIImage *)image width:(int)wdth height:(int)hght{
int w = image.size.width;
int h = image.size.height;
CGImageRef imageRef = [image CGImage];
int width, height;
int destWidth = wdth;
int destHeight = hght;
if(w > h){
width = destWidth;
height = h*destWidth/w;
}
else {
height = destHeight;
width = w*destHeight/h;
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmap;
bitmap = CGBitmapContextCreate(NULL, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedFirst);
if (image.imageOrientation == UIImageOrientationLeft) {
CGContextRotateCTM (bitmap, M_PI/2);
CGContextTranslateCTM (bitmap, 0, -height);
} else if (image.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM (bitmap, -M_PI/2);
CGContextTranslateCTM (bitmap, -width, 0);
}
else if (image.imageOrientation == UIImageOrientationUp) {
} else if (image.imageOrientation == UIImageOrientationDown) {
CGContextTranslateCTM (bitmap, width,height);
CGContextRotateCTM (bitmap, -M_PI);
}
CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *result = [UIImage imageWithCGImage:ref];
CGContextRelease(bitmap);
CGImageRelease(ref);
return result;
}