[英]How to make an area black, outside of a cgrect on a UIImage?
I am using OpenCV to detect face in an image, however my question is not related to opencv, i think its related to the CoreGraphics only. 我正在使用OpenCV来检测图像中的人脸,但是我的问题与opencv无关,我认为它仅与CoreGraphics有关。 Here is my code in a UIImageView (category) for detecting face and drawing a rectangle over it. 这是我在UIImageView(类别)中的代码,用于检测人脸并在其上绘制矩形。
- (void)detectFeature:(NSString *)feature
{
NSUInteger scale;
IplImage * image;
IplImage * smallImage;
NSString * xmlPath;
CvHaarClassifierCascade * cascade;
CvMemStorage * storage;
CvSeq * faces;
UIAlertView * alert;
CGImageRef imageRef;
CGColorSpaceRef colorSpaceRef;
CGContextRef context;
CvRect rect;
CGRect faceRect;
scale = 2;
cvSetErrMode( CV_ErrModeParent );
xmlPath = [ [ NSBundle mainBundle ] pathForResource: feature ofType: @"xml" ];
if (xmlPath == nil) {
NSLog(@"we don't have an xml file for this feature. this feature is can not be detacted");
}
else {
[self scaleAndRotateImage:self.image];
image = [ self createIplImage: self.image ];
smallImage = cvCreateImage( cvSize( image->width / scale, image->height / scale ), IPL_DEPTH_8U, 3 );
cvPyrDown( image, smallImage, CV_GAUSSIAN_5x5 );
cascade = ( CvHaarClassifierCascade * )cvLoad( [ xmlPath cStringUsingEncoding: NSASCIIStringEncoding ], NULL, NULL, NULL );
storage = cvCreateMemStorage( 0 );
faces = cvHaarDetectObjects( smallImage, cascade, storage, ( float )1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize( 20, 20 ) );
cvReleaseImage( &smallImage );
imageRef = self.image.CGImage;
colorSpaceRef = CGColorSpaceCreateDeviceRGB();
context = CGBitmapContextCreate
(
NULL,
self.image.size.width,
self.image.size.height,
8,
self.image.size.width * 4,
colorSpaceRef,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault
);
CGContextDrawImage
(
context,
CGRectMake( 0, 0, self.image.size.width, self.image.size.height ),
imageRef
);
CGContextSetLineWidth( context, 1 );
CGContextSetRGBStrokeColor( context, ( CGFloat )0, ( CGFloat )0, ( CGFloat )0, ( CGFloat )0.5 );
CGContextSetRGBFillColor( context, ( CGFloat )1, ( CGFloat )1, ( CGFloat )1, ( CGFloat )0.5 );
if( faces->total == 0 )
{
alert = [ [ UIAlertView alloc ] initWithTitle: @"No Feature" message: @"No features were detected in the picture. Please try with another one." delegate: NULL cancelButtonTitle: @"OK" otherButtonTitles: nil ];
[ alert show ];
}
else
{
for( int i = 0; i < faces->total; i++ )
{
rect = *( CvRect * )cvGetSeqElem( faces, i );
faceRect = CGContextConvertRectToDeviceSpace( context, CGRectMake( rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale ) );
CGContextFillRect( context, faceRect );
CGContextStrokeRect( context, faceRect );
}
self.image = [ UIImage imageWithCGImage: CGBitmapContextCreateImage( context ) ];
}
CGContextRelease( context );
CGColorSpaceRelease( colorSpaceRef );
cvReleaseMemStorage( &storage );
cvReleaseHaarClassifierCascade( &cascade );
cvReleaseImage( &smallImage );
}
}
What this code does is, it draws a rectangle over my UIImage. 这段代码所做的是,它在我的UIImage上绘制了一个矩形。 and leave the rest of the image as it is. 并保留其余图像。 I would like to change all the area of UIImage to black except the detected rectangle. 我想将UIImage的所有区域更改为黑色(检测到的矩形除外)。
As of right now, i have managed to crop the image. 截至目前,我已成功裁剪图像。 But i don't want to do that. 但是我不想那样做。 the size of the image should be same, i just want to black out the rest of the area of the image. 图像的大小应该相同,我只想涂黑图像的其余区域。
I have broken my ans in steps.Hope it helps. 我已逐步将ans弄断了,希望能有所帮助。
After detecting all faces, draw the filled rect, instead of path as new image. 检测完所有面部后,绘制填充的矩形,而不是将路径绘制为新图像。 There after draw a black image, of original images size. 在此之后绘制一张黑色图像,其大小与原始图像相同。
Thenceforth create a new context , draw black image, then drew the path image(image with rect path) with kCGBlendModeDestinationOut blend mode.Save the result as result1. 此后创建一个新上下文,绘制黑色图像,然后使用kCGBlendModeDestinationOut混合模式绘制路径图像(带有正路径的图像)。将结果保存为result1。
Again create a new context , draw original image, then draw the path image(image with rect path) with kCGBlendModeDestinationIn blend mode.Save the result as result2. 再次创建一个新的上下文,绘制原始图像,然后使用混合模式kCGBlendModeDestination绘制路径图像(带有正路径的图像)。将结果保存为result2。
Take a new context draw both images result1 and result2 kCGBlendModeNormal. 在新的上下文中绘制图像result1和result2 kCGBlendModeNormal。 Hope it helps. 希望能帮助到你。 Happy Coding.. !! 快乐编码.. !!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.