Re: Best way to composite/tile multiple CGImages to one image
Re: Best way to composite/tile multiple CGImages to one image
- Subject: Re: Best way to composite/tile multiple CGImages to one image
- From: Kevin Meaney <email@hidden>
- Date: Wed, 19 Mar 2014 16:21:00 +0000
On 18 Mar 2014, at 14:22, Jim Crate <email@hidden> wrote:
>
> I would start with something like this:
>
> CIImage *img = [CIImage emptyImage];
> for … {
> // calculate tile position from index, create NSAffineTransform for scaling/translating
> CGImageRef tileRef = // get image from AV framework
> CIImage *tile = [CIImage imageWithCGImage:tileRef];
>
> CIFilter *f = [CIFilter filterWithName:@"CIAffineTransform"];
> [f setValue:transform forKey:kCIInputTransformKey];
> [f setValue:tile forKey:kCIInputImageKey];
> tile = [f valueForKey:kCIOutputImageKey];
>
> CIFilter *f = [CIFilter filterWithName:@"CISourceOverCompositing"];
> [f setValue:img forKey:kCIInputBackgroundImageKey];
> [f setValue:tile forKey:kCIInputImageKey];
> img = [f valueForKey:kCIOutputImageKey];
>
> // you’ll need to figure out whether it is safe to CGImageRelease your grabbed CGImageRef here
> // or if you need to keep track of them and release them at the end of the process
> }
>
> // you’ll have to figure out your colorspace and bitmap info
> CGColorSpaceRef colorSpace = CGImageGetColorSpace(imgRef);
> CGBitmapInfo bitmapInfo = CGImageGetAlphaInfo(imgRef);
> CGContextRef cgContext = CGBitmapContextCreate(NULL, destRect.size.width, destRect.size.height, 8, 0, colorSpace, bitmapInfo);
>
> CIContext *ciContext = [CIContext contextWithCGContext:cgContext options:nil];
> CGImageRef tiledImageRef = [ciContext createCGImage:img fromRect:[img extent]];
>
> // save the image using ImageIO
> CGImageDestinationRef destRef = CGImageDestinationCreateWithURL((__bridge CFURLRef)destURL, (__bridge CFStringRef)imageType, 1, NULL);
> CGImageDestinationSetProperties(destRef, (__bridge CFDictionaryRef)propsDict);
> CGImageDestinationAddImage(destRef, tiledImageRef, (__bridge CFDictionaryRef)propsDict);
> CGImageDestinationFinalize(destRef);
>
> CGImageRelease(imageRef);
> CFRelease(destRef);
>
>
> If you wanted better thumbnail image quality, you could use the Lanczos filter first, then just use the NSAffineTransform to translate the picture to the proper tile position. Also, I see there is an imageByApplyingTransform method that takes a CGAffineTransform, so it may be even simpler if you’d rather use that.
I felt the need to give this a go and I've produced a little command line tool that tests this out. I've also provided some performance results for a few options. I've gone for the CILanczosTransform filter, I don't know if that slows things down, a quick look at the profile results didn't appear to show that any one area dominated overly so I've not done anything to try and optimize but at the same time I'm not that impressed with the speed.
I was also going to try and include an option for the command line to select creating the coversheets using coregraphics and gcd to achieve concurrency but the more I thought about the harder it seemed to integrate the two different approaches into 1 tool. I'm going to try write a new tool to do that. Perhaps once I've finished it I'll better be able to see how both approaches can be integrated.
The information including code etc. you can view at the git hub repository where I've saved stuff.
https://github.com/SheffieldKevin/makecoversheet
Kevin
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden