views:

389

answers:

3

I need to horizontally flip some video I'm previewing and capturing. A-la iChat, I have a webcam and want it to appear as though the user is looking in a mirror.

I'm previewing Quicktime video in a QTCaptureView. My capturing is done frame-by-frame (for reasons I won't get into) with something like:

imageRep = [NSCIImageRep imageRepWithCIImage: [CIImage imageWithCVImageBuffer: frame]];
image = [[NSImage alloc] initWithSize: [imageRep size]];
[image addRepresentation: imageRep];
[movie addImage: image forDuration: someDuration withAttributes: someAttributes];

Any tips?

+1  A: 

You could do this by taking the CIImage you're getting from the capture and running it through a Core Image filter to flip the image around. You would then pass the resulting image into your image rep rather than the original one. The code would look something like:

CIImage* capturedImage = [CIImage imageWithCVImageBuffer:buffer];
NSAffineTransform* flipTransform = [NSAffineTransform transform];
CIFilter* flipFilter;
CIImage* flippedImage;

[flipTransform scaleByX:-1.0 y:1.0]; //horizontal flip
flipFilter = [CIImage filterWithName:@"CIAffineTransform"];
[flipFilter setValue:flipTransform forKey:@"inputTransform"];
[flipFilter setValue:capturedImage forKey:@"inputImage"];
flippedImage = [flipFilter valueForKey:@"outputImage"];
imageRep = [NSCIImageRep imageRepWithCIImage:flippedImage];
...
Brian Webster
That looks like it will probably work for recording, but what about in the `QTCaptureView`?
Dan
Something like this might work, using the same setup for the flipFilter variable as above:[captureView setWantsLayer:YES];captureView.layer.filters = [NSArray arrayWithObject:flipFilter];
Brian Webster
Awesome - that appears to work great! I had to add a translate transform by the negative of the view's width to move the flipped video back where it should be, but that was easy.
Dan
Just for the record: this seems to really drag the processor. Photobooth and iChat must do it a different way...
Dan
Just noticed QTCaptureView has a delegate method, view:willDisplayImage:, that lets you modify the CIImage it's about to draw. Might be worth a shot.
Brian Webster
+2  A: 

Nothing like resurrecting an old question. Anyway I came here and almost found what I was looking for thanks to Brian Webster but if anyone is looking for the wholesale solution try this after setting your class as the delegate of the QTCaptureView instance:

- (CIImage *)view:(QTCaptureView *)view willDisplayImage:(CIImage *)image {
//mirror image across y axis
return [image imageByApplyingTransform:CGAffineTransformMakeScale(-1, 1)];
}
bmalicoat
A: 

Thanx alot for this QTKit/Core Video mirror filter code example. Saved my day!

Dan