I want to add an UIImage
in the UIImageView
of the UITableViewCell
inside the UITableViewController
. This works fine:
cell.imageView.image = [UIImage imageNamed:@"myImage.png"];
But now, I want to merge two images and use the code I've found here:
UIImage *mergedImage = [MyUtils mergeImage:@"myBackImage.png" withImage:@"myFrontImage.png"];
This works very good with an old iPhone (320x480) but not on retina display. In my project, there are "@2x"-versions of every image. I analyze the code and have an explanation for the problem.
a) on iPhone 3 without merging (WORKS)
- image width: 28.0
- image height: 29.0
- image scale: 1.0
b) on iPhone 3 with merging (WORKS)
- image width: 28.0
- image height: 29.0
- image scale: 1.0
c) on iPhone 4 without merging (WORKS)
- image width: 28.0
- image height: 29.0
- image scale: 2.0
d) on iPhone 4 with merging (WORKS NOT)
- image width: 56.0
- image height: 58.0
- image scale: 1.0
As you can see, the merging converts the "28.0/29.0/2.0" to an "56.0/58.0/1.0" image. And this images gets displayed to big on retina display.
How can I correctly merge two images to get an image with a scale of 2.0?
+ (UIImage*)mergeImage:(UIImage*)first withImage:(UIImage*)second
{
// get size of the first image
CGImageRef firstImageRef = first.CGImage;
CGFloat firstWidth = CGImageGetWidth(firstImageRef);
CGFloat firstHeight = CGImageGetHeight(firstImageRef);
// get size of the second image
CGImageRef secondImageRef = second.CGImage;
CGFloat secondWidth = CGImageGetWidth(secondImageRef);
CGFloat secondHeight = CGImageGetHeight(secondImageRef);
// build merged size
CGSize mergedSize = CGSizeMake(MAX(firstWidth, secondWidth), MAX(firstHeight, secondHeight));
// capture image context ref
UIGraphicsBeginImageContext(mergedSize);
//Draw images onto the context
[first drawInRect:CGRectMake(0, 0, firstWidth, firstHeight)];
[second drawInRect:CGRectMake(0, 0, secondWidth, secondHeight)];
// assign context to new UIImage
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// end context
UIGraphicsEndImageContext();
return newImage;
}
You need to compute the merged size based on the UIImage
sizes, not the CGImage
sizes, and you need to create the graphics context using the largest of the image's scales. Try this:
CGSize firstSize = first.size;
CGSize secondSize = second.size;
CGSize mergedSize = CGSizeMake(MAX(firstSize.width, secondSize.width),
MAX(firstSize.height, secondSize.height));
CGFloat mergedScale = MAX(first.scale, second.scale);
UIGraphicsBeginImageContextWithOptions(mergedSize, NO, mergedScale);
[first drawAtPoint:CGPointZero];
[second drawAtPoint:CGPointZero];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;