Crop an image without using an image mask?

I am trying to add a feature to my iPhone application that allows users to record a screen. To do this, I used an open source class called ScreenCaptureView , which compiles a series of screenshots of the main view using the renderInContext: method. However, this method ignores masked CALayers, which is the key for my application.

EDIT: I need a way to record the screen so the masks are on. Although this question specifically addresses how to create the illusion of an image mask, I am open to any other modifications that I can make to successfully record a screen.

DESCRIPTION APP

In the application, I take a picture and create the effect of a moving mouth, animating the position of the jaw area, as shown below.

enter image description hereenter image description here

Currently, I have the whole face as one CALayer, and the chin area as a separate CALayer. To make the chin layer, I mask the chin area from a full face with CGPath. (This path is irregular in shape and must be dynamic).

enter image description here

 - (CALayer *)getChinLayerFromPic:(UIImage *)pic frame:(CGRect)frame { CGMutablePathRef mPath = CGPathCreateMutable(); CGPathMoveToPoint(mPath, NULL, p0.x, p0.y); CGPoint midpt = CGPointMake( (p2.x + p0.x)/2, (p2.y+ p0.y)/2); CGPoint c1 = CGPointMake(2*v1.x - midpt.x, 2*v1.y - midpt.y); //control points CGPoint c2 = CGPointMake(2*v2.x - midpt.x, 2*v2.y - midpt.y); CGPathAddQuadCurveToPoint(mPath, NULL, c1.x, c1.y, p2.x, p2.y); CGPathAddQuadCurveToPoint(mPath, NULL, c2.x, c2.y, p0.x, p0.y); CALayer *chin = [CALayer layer]; CAShapeLayer *chinMask = [CAShapeLayer layer]; chin.frame = frame; chin.contents = (id)[pic CGImageWithProperOrientation]; chinMask.path = mPath; chin.mask = chinMask; CGPathRelease(mPath); return chin; } 

Then I animate the chin layer with the path animation.

As mentioned earlier, the renderInContext: method ignores the mask and returns an image of the entire face, not just the chin. Is there a way to create the illusion of disguising the chin? I would like to use CALayers if possible, as this would be most convenient for animations. However, I am open to any ideas, including other ways to capture video. Thanks.

EDIT: I rotate the trimmed chin in UIImage and then set this new image as the contents of the layers, rather than directly masking the layer. However, the cropped area is the reverse of the specified path.

  CALayer *chin = [CALayer layer]; chin.frame = frame; CGImageRef imageRef = [pic CGImage]; CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); int targetWidth = frame.size.width; int targetHeight = frame.size.height; CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); CGContextRef bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); CGContextAddPath(bitmap, mPath); CGContextClip(bitmap); CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef); CGImageRef ref = CGBitmapContextCreateImage(bitmap); UIImage *chinPic = [UIImage imageWithCGImage:ref]; chin.contents = (id)[chinPic CGImageWithProperOrientation]; 
+4
source share
4 answers

Why don't you draw a CALayer chin in a separate CGImage and create a new UIImage with this? Then you can add this CGImage to a separate UIImageView, which you can just move with PanGestureRecognizer, for example?

0
source

I suggest you draw each part alone (you don’t need masks), a face without a chin and a chin, both with alpha pixels around, and then just pull up the chin and move it to your path.

Please tell me if this did not help you, welcome

0
source

If you just need this to capture the screen, it’s much easier to use a program like

http://www.airsquirrels.com/reflector/

which connects your device to your computer via AirPlay and then records the stream to your computer. This particular program has a built-in screen recording, extremely convenient. I think there is a trial version that you can use to record up to 10 minutes.

0
source

Have you tried to look at layer.renderInContext not taking into account layer.mask? ?

In particular (note the coordinate flip):

 //Make the drawing right with coordinate switch CGContextTranslateCTM(context, 0, cHeight); CGContextScaleCTM(context, 1.0, -1.0); CGContextClipToMask(context, CGRectMake(maskLayer.frame.origin.x * mod, maskLayer.frame.origin.y * modTwo, maskLayer.frame.size.width * mod,maskLayer.frame.size.height * modTwo), maskLayer.image.CGImage); //Reverse the coordinate switch CGAffineTransform ctm = CGContextGetCTM(context); ctm = CGAffineTransformInvert(ctm); CGContextConcatCTM(context, ctm); 
0
source

Source: https://habr.com/ru/post/1486147/


All Articles