views:

169

answers:

1

hi,

I am developing an iPhone app that resizes and merges images.

I want to select two photos of size 1600x1200 from photo library and then merge both into a single image and save that new image back to the photo library.

However, I can't get the right size for the merged image.

I take two image views of frame 320x480 and set the view's image to my imported images. After manipulating the images (zooming, cropping, rotating), I then save the image to album. When I check the image size it shows 600x800. How do I get the original size of 1600*1200?

I've been stuck on this problem from two weeks!

Thanks in advance.

A: 

The frame of the UIImageView has nothing to do with the size of the image it displays. If you display a 1200x1600 pixel in a 75x75 imageView the image size in memory is still 1200x1600. Somewhere in your processing of the image you are resetting its size.

You need to resize the images programmatically behind the scenes and ignore how they are displayed. For highest fidelity, I suggest preforming all processing on the image at full size and then resizing only the final result. For speed and low memory use, resize smaller first, process and then resize again as needed.

I use Trevor Harmon's UIImage+Resize to resize images.

His core method looks like this:

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

Harmon saved me dozens of man hours trying to get resizing done correctly.

TechZen
thanks for response,i am also doing same this way.. processing all the code in resized images and after that again resizing it. But it gives image blur... but image need not loose its original quality..
maddy
If you resize the logical (as opposed to the display) image you will inevitably loose some resolution because the resizing algorithm must perform some interpolation/extrapolation in order to shrink/expand the image. In doing so it destroys some of the information that originally defined the image.
TechZen
When deciding what order to perform graphical processing at the highest fidelity, you should go in sequences of the least altering to the most. E.g Composite-->crop-->rotate-->scale-->resize.
TechZen
finally i am succeeded little bit . while saving again i am taking two image views of 1200*1600 size and applying all transforms to that image views what we have got from previous 320*480 views. its working fine.But the issue is its not getting proper, because we taken transforms of 320*480 view. so how to overcome this issue.Thanks in advance.
maddy
You should not be transforming the view e.g. myImageView.transform (Except for display purposes). Instead, you should be transforming the logical image and then simply displaying that in the ImageView. The size of the ImageView should be irrelevant to size of the image. It's okay to use the Imageview as a control to show the image being rotated, scaled etc but you should not be actually transforming both the view and the image at the same time. Transforming the view and transforming the logical image should be two separate pieces of code.
TechZen
I would suggest completely ignoring the UI and instead get your transform working as they would in a command line app with no GUI. In the app delegate's `applicationDidFinishLaunching`, comment the code that opens the window and the initial view. Then programmatically call the methods that transform image (they should be in a self contained class anyway). Save the images to disk to check them visually. Get that behind the scenes code working perfectly before you even think about bringing the UI into the picture. Then, it becomes a matter of linking the UI to the perfectly working code.
TechZen