On Mar 14, 2014, at 5:30 PM, Trygve Inda <[email protected]> wrote:
> So what is the best way to use CoreImage in this case?
>
> I get the original large CGImageRef using an AVImageGenerator which grabs a
> frame from a video file.
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.
See the following URLs for more info:
https://developer.apple.com/library/mac/documentation/graphicsimaging/conceptual/CoreImaging/ci_intro/ci_intro.html
https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html
Another option would be to use:
- (void)generateCGImagesAsynchronouslyForTimes:(NSArray *)requestedTimes
completionHandler:(AVAssetImageGeneratorCompletionHandler)handler
and do the CIImage processing in the completion handler. I’m not sure how you
would determine that you were finished grabbing images, though, so that method
may be more suited to the type of processing you would do if each frame grab
was saved to an individual file, for instance. If you want to use multiple
cores, it may be easier to use an NSOperationQueue and effectively process each
run through the loop as an individual operation, and then you can generate the
jpeg in a final operation that depends on the other operations finishing (very
simple, but get it working first).
Jim
_______________________________________________
Cocoa-dev mailing list ([email protected])
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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]