Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Resizing a photo to a new UIImage

cmezakcmezak Posts: 207Registered Users
edited September 2011 in iPhone SDK Development
This is crazy. I know there are threads that touch on this already, but none of them have led me to the answer. I can't believe that it is really this difficult!

I want to get an image from the camera via UIImagePicker and resize the image so I can use it in my app. Fullsize images from the camera are far too large to hold in memory in large numbers. I can handle the ImgePicker fine. But once I get the fullsize image from it, I need to resize the image.

For the life of me, I can't figure out how to accomplish this simple task.

From what I've read so far, I have to do some quartz2d programming using bitmatcontexts and transforms. The results so far are not good. even when I can get an image out of the other end of my code, it is not oriented correctly or it is stretched the wrong way. If I attempt to apply more transforms to fix the problem, I'm thwarted again.

I know this is a rant and a cop out, but could someone help me get to a simple function that look like this:
- (UIImage *)resizeImage:(UIImage *)original (CGSize)newSize {

* * * MAGIC * * * 

return resizedImage (not resized and stretched or resized and rotated!)

}

I'd post some of my own code, but it is mostly hacked up versions of code I've found elsewhere on the net. I'm a fine iPhone programmer, but I've never dealt with low-level image stuff. I hoped that such a simple task as resizing an image would not be so difficult!

- Charlie
Post edited by cmezak on
«1

Replies

  • pinpointpinpoint Posts: 59Registered Users @
    edited December 2008
    Here's a solution that has worked for me so far.
    I got most if not all of the code from another post here. I did have to hard code the alpha setting or I got a run-time error.

    I won't pretend to know how it works at this point, but it does the job.
    I'm having memory leaks at the moment, but I suspect they're related to other parts of my code not this.
    -(UIImage *)resizeImage:(UIImage *)image width:(int)width height:(int)height {
    	
    	CGImageRef imageRef = [image 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;	
    }
    
    <font color="Red">Dave Peat</font><br />
    <a href="http://iphone.pinpointsolutionsinc.com" target="_blank">Pinpoint Solutions, Inc.</a>
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    I get this error when I run that code:

    Wed Dec 3 13:27:41 CMEZAK.WIFI.WPI.EDU cameraTest[41687] <Error>: CGBitmapContextCreate: unsupported parameter combination: 5 integer bits/component; 16 bits/pixel; 3-component colorspace; kCGImageAlphaNoneSkipLast; 200 bytes/row.
    Wed Dec 3 13:27:41 CMEZAK.WIFI.WPI.EDU cameraTest[41687] <Error>: CGContextDrawImage: invalid context
    Wed Dec 3 13:27:41 CMEZAK.WIFI.WPI.EDU cameraTest[41687] <Error>: CGBitmapContextCreateImage: invalid context
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    Using this code gets me an image, but the color is wrong:
    -(UIImage *)resizeImage:(UIImage *)image width:(int)width height:(int)height {
    	
    	CGImageRef imageRef = [image CGImage];
    	CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
    	CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    	
    	if (alphaInfo == kCGImageAlphaNone)
    	alphaInfo = kCGImageAlphaNoneSkipLast;
    	
    	CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, alphaInfo);
    	CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);
    	CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    	UIImage *result = [UIImage imageWithCGImage:ref];
    	
    	CGContextRelease(bitmap);
    	CGImageRelease(ref);
    	
    	return result;	
    }
    

    The resulting image looks like this:

    cameratest.png

    - Charlie
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    Does the problem have to do with bytes per row? Since I am resizing, do I have to do a conversion?

    - Charlie
  • pinpointpinpoint Posts: 59Registered Users @
    edited December 2008
    From the prior post, I think the issue is with the alpha setting.
    I received a similar error, and that's why i hard coded the alpha setting the way I did.

    Not knowing exactly what I was doing of course leaves me wide open to an image with parms I don't expect blowing up or looking differently than i'd like.

    If anyone can shed some light on this i'd be very interested! I just don't have time to look at the docs right now
    <font color="Red">Dave Peat</font><br />
    <a href="http://iphone.pinpointsolutionsinc.com" target="_blank">Pinpoint Solutions, Inc.</a>
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    I've been looking at the docs, and they're not too helpful. I'm surprised, because this seems like an essential iphone task.

    - Charlie
  • BostonMerlinBostonMerlin Posts: 399Registered Users
    edited December 2008
    I am looking to do exactly the same thing. Take a picture, resize the image to just the size of the iphones screen.. then save it. That image is being sent out to a server and back out to other phones.. need to get the filesize down. I'm already using UIImageJPEGRepresentation with a compression of 0.0 but they're still way too big for what's needed.

    If anyone can help move this along I would be forever grateful!

    Thanks
    john

    <br />
    <b>I love being a dad, flying airplanes and writing code.</b><br />
    <br />
    Follow me on Twitter: <a href=
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    Here is my code to shrink the camera's output to 640x480.

    I can't claim mastery of what happens in it -- it's the result of a good deal of struggle -- but at least it works!

    If you tweak it or make it more flexible/robust, please post the result here!

    - Charlie
    -(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;	
    }
    
  • BostonMerlinBostonMerlin Posts: 399Registered Users
    edited December 2008
    Thanks Charlie. I'll give this a whirl. I started messing around with code from another thread and it's causing all kinds of weirdness.

    John

    <br />
    <b>I love being a dad, flying airplanes and writing code.</b><br />
    <br />
    Follow me on Twitter: <a href=
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    Yeah. I found that handling the transforms to correctly orient the images was the most tricky part. The documentation for this is not clear. Also, I found that images from the photo library come out pink. I couldn't resolve this, but since my app is using images from the camera (which come out just fine) it's not a big deal for me.

    Good luck!

    - Charlie
  • BostonMerlinBostonMerlin Posts: 399Registered Users
    edited December 2008
    Hey Charlie.. I'm getting an error on the following line of code.. looks like you have another method out there I need or need to reference another library?

    Error: Implicit declaration of function radians..

    CGContextRotateCTM (bitmap, radians(90));

    Thoughts?

    Thanks again
    John

    <br />
    <b>I love being a dad, flying airplanes and writing code.</b><br />
    <br />
    Follow me on Twitter: <a href=
  • cmezakcmezak Posts: 207Registered Users
    edited December 2008
    Oh right. That's just something Apple recommends in the documentation on CTM transforms in the quartz2d programming guide. I suggest you check it out, though it didn't clear up all of my questions.

    Anyway, the missing function just translates degrees into radians, which are what those methods need. Here it is:
    #include <math.h>
    static inline double radians (double degrees) {return degrees * M_PI/180;}
    
  • narutnarut Posts: 43Registered Users
    edited January 2009
    cmezak wrote: »
    Yeah. I found that handling the transforms to correctly orient the images was the most tricky part. The documentation for this is not clear. Also, I found that images from the photo library come out pink. I couldn't resolve this, but since my app is using images from the camera (which come out just fine) it's not a big deal for me.

    Good luck!

    - Charlie
    First of all, thanks for the code cmezak. You really did save my life. :)

    I'm totally newbie about Quartz, but from trial and error, I've managed to get the code working for both camera and library.
    Looks like the photo from library turn pink because CGImageGetBitsPerComponent(imageRef) will always return 5 bits per component (got 8 bits from camera images).
    I'm not sure if the Generic RGB Color Space returned from CGColorSpaceCreateDeviceRGB() will assume that you use 8 bits/component picture. So that's why only the images from library was not processed properly.

    Here's what I do
    bitmap = CGBitmapContextCreate(NULL, longSide, shortSide, 8, image.size.width*3, 
    CGColorSpaceCreateDeviceRGB(), alphaInfo);
    

    Not even sure if there would be any bad side effects for harding code like this. But I think I'm gonna keep it this way until I learn more about Quartz things. :)
  • MikeRieggerMikeRiegger Posts: 4New Users
    edited February 2009
    Hey thanks for the excellent example cmezek! :cool:

    Two things I noticed though, I think you might need a:

    CGColorSpaceRelease(colorSpaceInfo);

    In the above example. Also, should:


    if (image.imageOrientation == UIImageOrientationUp | image.imageOrientation == UIImageOrientationDown) {


    that be a || instead of a |?

    Anyway, the code is working great though on my iphone, thanks for posting it.

    -Michael Riegger
  • rocazrocaz Posts: 8New Users
    edited February 2009
    Good stuff--I have slightly different need. I am wondering if someone looking at this thread has already figured this "easier" version out. I don't want to transform the data--I just want to set the same rotation flag that Apple uses in its stored photos. If you process the nominal data it appears that the data is rotated landscape vs. portrait (in the nominal position). I believe imageOrientation is the key (UIImage) but that particular data member is read only according to the docs. I haven't figured out how to set the same orientation in the output images. Anybody have an idea?
  • XenoSageXenoSage Posts: 48Registered Users
    edited March 2009
    here's what i think to be an easier way to resize and image.
    UIGraphicsBeginImageContext( newSize );// a CGSize that has the size you want
       [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    //image is the original UIImage
       UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
       UIGraphicsEndImageContext();
    

    newImage is your newly created image with the size you want
  • bhearnbhearn Posts: 125Registered Users
    edited March 2009
    XenoSage wrote: »
    here's what i think to be an easier way to resize and image.
    UIGraphicsBeginImageContext( newSize );// a CGSize that has the size you want
       [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    //image is the original UIImage
       UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
       UIGraphicsEndImageContext();
    

    newImage is your newly created image with the size you want

    Yes, this is the easy way to do it -- unless you want to do it in a background thread:

    http://www.iphonedevsdk.com/forum/iphone-sdk-development/13963-background-threads-graphics.html

    Then it looks like you have to use something like the code here.
  • ralmeidaralmeida Posts: 2New Users
    edited July 2009
    IT WORKS :)

    All above code with minimal tweaks:
    ...
    #include <math.h>
    
    static inline double radians (double degrees) {return degrees * M_PI/180;}
    ...
    
    
    -(UIImage *)resizeImage:(UIImage *)image :(NSInteger) width :(NSInteger) height {
    	
    	CGImageRef imageRef = [image CGImage];
    	CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
    	CGColorSpaceRef colorSpaceInfo = CGColorSpaceCreateDeviceRGB();
    	
    	if (alphaInfo == kCGImageAlphaNone)
    		alphaInfo = kCGImageAlphaNoneSkipLast;
    	
    	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];
    	
    	CGColorSpaceRelease(colorSpaceInfo);
    	CGContextRelease(bitmap);
    	CGImageRelease(ref);
    	
    	return result;	
    }
    
  • itayneemanitayneeman Posts: 5New Users
    edited August 2009
    The following code should take care of converting both PNG and JPG images, if someone is still having issues:
    -(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);
    		
    	}	
    	
    	
    	// In the right or left cases, we need to switch scaledWidth and scaledHeight,
    	// and also the thumbnail point
    	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; 
    }
    
  • salboysalboy Posts: 4New Users
    edited September 2009
    Thanks CMEZAK for a great solution.

    I just used the the function refined by itayneeman ... it works fine ... however when I try to load the image from Camera ... and when the application is in Release Mode ... it crashes on the device with the following warning ... [that usually comes when I use the function even in Simulator Debug mode]
    -[UIWindow endDisablingInterfaceAutorotation] called on <UIWindow:
    0xf19f70; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM;
    layer = <CALayer: 0xf1acb0>> without matching
    -beginDisablingInterfaceAutorotation. Ignoring.
    
    and I assume ... this is the main problem, that is causing me issues ... can any one shed some light on this ...

    need help urgently ... appreciate a quick response ...

    Regards,
    SaL
  • salboysalboy Posts: 4New Users
    edited September 2009
    OK ... that was dumb of me to ask a stupid question ... I just fixed it and error was not related to this topic at all ... it was just that I was dismissing a modal controller with animation ... after pushing a new controller to the view ... how insane :) ...
  • kobkobnkobkobn Posts: 1New Users
    edited November 2009
    ralmeida wrote: »
    IT WORKS :)

    All above code with minimal tweaks:
    ...
    #include <math.h>
    
    static inline double radians (double degrees) {return degrees * M_PI/180;}
    ...
    
    
    -(UIImage *)resizeImage:(UIImage *)image :(NSInteger) width :(NSInteger) height {
    	
    	CGImageRef imageRef = [image CGImage];
    	CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
    	CGColorSpaceRef colorSpaceInfo = CGColorSpaceCreateDeviceRGB();
    	
    	if (alphaInfo == kCGImageAlphaNone)
    		alphaInfo = kCGImageAlphaNoneSkipLast;
    	
    	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];
    	
    	CGColorSpaceRelease(colorSpaceInfo);
    	CGContextRelease(bitmap);
    	CGImageRelease(ref);
    	
    	return result;	
    }
    



    Hi,
    thanks a lot for the info.
    i've used the code and it does what it's expected but i do encounter some memory problems after using it.

    in my app, the user will select a photo form the photo lib, after selecting it, the application will display the photo in a UIImageView and later will be taken form the imageView for some processing.
    I'm a bit new to iphoen programming and most chances i'm doing something wrong.
    Since i want to fix the rotation problem, i use the method inorder ot resize the photo to the original size (by that i just fix the rotatin problem).
    I call the routine with the selected image size from the DidFinishPickingMediaWithInfo method (is it ok to call it from there ?)
    and after one or two selections i start to get memory warnings.
    what i do in DidFinishPickingMediaWithInfo is basicly :

    (assuming img is the original selected image :)

    [myImageView setImage:[self resizeImage:img height:img.size.height width:img.size.width];

    after that, as i said ... memory problem.

    Am i missing a way to only change the size for displaying the photo but using it later in its original size ?

    thanks a lot,
    Kobi.
  • TheaterGirl62TheaterGirl62 Posts: 4New Users
    edited January 2010
    salboy wrote: »
    OK ... that was dumb of me to ask a stupid question ... I just fixed it and error was not related to this topic at all ... it was just that I was dismissing a modal controller with animation ... after pushing a new controller to the view ... how insane :) ...

    THANK YOU - that error was driving me nuts and I had no idea what I was doing... (I was also changing the view under a modal view before dismissing the modal view).

    Now that I think of it... is there anything wrong with that? I feel like not, but I'm still relatively new at iPhone app stuff.
  • evan1466evan1466 Posts: 53Registered Users
    edited September 2011
    So I am using very similar code to what is above.

    Have been having issues resizing PNGs but only in the simulator.

    Any thoughts?

    CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component colorspace; kCGImageAlphaLast; 970 bytes/row.
    Match aPhoto - Your Memory Game!
  • evan1466evan1466 Posts: 53Registered Users
    edited September 2011
    -(UIImage*)imageByScalingProportionallyToMinimumSize:(UIImage *)imageIn :(CGSize)targetSize{	
    	UIImage *sourceImage = imageIn;
    	CGSize imageSize = sourceImage.size;
    	CGFloat width = imageSize.width;
    	CGFloat height = imageSize.height;
    	CGFloat targetWidth = targetSize.width;
    	CGFloat targetHeight = targetSize.height;    
        if([[UIScreen mainScreen]respondsToSelector:@selector(scale)]&&(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad)) { 
    		CGFloat scale = [[UIScreen mainScreen] scale];
    		targetWidth = targetWidth*scale;
    		targetHeight = targetHeight*scale;
    	}
    	CGFloat scaleFactor = 1.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;
    		
    		if (widthFactor > heightFactor) {
    			thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
    		} else if (widthFactor < heightFactor) {
    			thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    		}
    	}
    	CGImageRef imageRef = [sourceImage CGImage];
    	CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
    	CGColorSpaceRef colorSpaceInfo = CGColorSpaceCreateDeviceRGB();
    	
    	if (alphaInfo == kCGImageAlphaNone)
    		alphaInfo = kCGImageAlphaNoneSkipLast;
    	
    	CGContextRef bitmap;
    	
    	if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
    		bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), 4*targetWidth, colorSpaceInfo, alphaInfo);
    		
    	} else {
    		bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), 4*targetWidth, colorSpaceInfo, alphaInfo);
    		
    	}
    	if (sourceImage.imageOrientation == UIImageOrientationLeft) {
    		NSLog(@"image orientation left");
    		CGContextRotateCTM (bitmap, radians(90));
    		CGContextTranslateCTM (bitmap, 0, -height);
    		
    	} else if (sourceImage.imageOrientation == UIImageOrientationRight) {
    		NSLog(@"image orientation right");
    		CGContextRotateCTM (bitmap, radians(-90));
    		CGContextTranslateCTM (bitmap, -width, 0);
    		
    	} else if (sourceImage.imageOrientation == UIImageOrientationUp) {
    		NSLog(@"image orientation up");	
    		
    	} else if (sourceImage.imageOrientation == UIImageOrientationDown) {
    		NSLog(@"image orientation down");	
    		CGContextTranslateCTM (bitmap, targetWidth,targetHeight);
    		CGContextRotateCTM (bitmap, radians(-180.));
    	}
        
    	CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef);
    	CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    	UIImage *result;
        if([[UIScreen mainScreen]respondsToSelector:@selector(scale)]&&(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad)) { 
    		float scale = [[UIScreen mainScreen] scale];
    		result = [UIImage imageWithCGImage:ref scale:scale orientation:UIImageOrientationUp];
    	} else {
    		result = [UIImage imageWithCGImage:ref];
    	}
    	CGColorSpaceRelease(colorSpaceInfo);
    	CGContextRelease(bitmap);
    	CGImageRelease(ref);
    	
    	return result;	
    }
    
    Match aPhoto - Your Memory Game!
«1
Sign In or Register to comment.