objective-c 使用 CGImageMaskCreate 创建蒙版是全黑的 (iphone)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/633051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:14:00  来源:igfitidea点击:

Creating mask with CGImageMaskCreate is all black (iphone)

iphoneobjective-ccocoa-touchimage-manipulationquartz-graphics

提问by Patrick

I'm trying to create an image mask that from a composite of two existing images.

我正在尝试从两个现有图像的合成中创建一个图像蒙版。

First I start with creating the composite which consists of a small image that is the masking image, and a larger image which is the same size as the background:

首先,我从创建合成图开始,该合成图由作为遮罩图像的小图像和与背景大小相同的较大图像组成:

UIImage * BaseTextureImage = [UIImage imageNamed:@"background.png"];
UIImage * MaskImage = [UIImage imageNamed:@"my_mask.jpg"];
UIImage * ShapesBase = [UIImage imageNamed:@"largerimage.jpg"];
UIImage * MaskImageFull;

CGSize finalSize = CGSizeMake(480.0, 320.0);
UIGraphicsBeginImageContext(finalSize);
[ShapesBase drawInRect:CGRectMake(0, 0, 480, 320)];
[MaskImage drawInRect:CGRectMake(150, 50, 250, 250)];
MaskImageFull = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

I can output this UIImage (MaskImageFull) and it looks right, it is a fullsize background size and it is a white background with my mask object in black, in the right place on the screen.

我可以输出这个 UIImage (MaskImageFull),它看起来是正确的,它是一个全尺寸的背景尺寸,它是一个白色背景,我的遮罩对象是黑色的,在屏幕上的正确位置。

I then pass the MaskImageFull UIImage through this:

然后我通过这个传递 MaskImageFull UIImage :

CGImageRef maskRef = [maskImage CGImage];
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
    CGImageGetHeight(maskRef),
    CGImageGetBitsPerComponent(maskRef),
    CGImageGetBitsPerPixel(maskRef),
    CGImageGetBytesPerRow(maskRef),
    CGImageGetDataProvider(maskRef), NULL, false);

CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
UIImage* retImage= [UIImage imageWithCGImage:masked];

The problem is that the retImage is all black. If I send a pre-made UIImage in as the mask it works fine, it is just when I try to make it from multiple images that it breaks.

问题是 retImage 是全黑的。如果我发送一个预制的 UIImage 作为掩码,它可以正常工作,只有当我尝试从多个图像制作它时,它才会中断。

I thought it was a colorspace thing but couldn't seem to fix it. Any help is much appreciated!

我认为这是一个色彩空间的事情,但似乎无法修复它。任何帮助深表感谢!

回答by catlan

I tried the same thing with CGImageCreateWithMask, and got the same result. The solution I found was to use CGContextClipToMask instead:

我用 CGImageCreateWithMask 尝试了同样的事情,并得到了相同的结果。我找到的解决方案是使用 CGContextClipToMask 代替:

CGContextRef mainViewContentContext;
CGColorSpaceRef colorSpace;

colorSpace = CGColorSpaceCreateDeviceRGB();

// create a bitmap graphics context the size of the image
mainViewContentContext = CGBitmapContextCreate (NULL, targetSize.width, targetSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);

// free the rgb colorspace
CGColorSpaceRelease(colorSpace);    

if (mainViewContentContext==NULL)
    return NULL;

CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage];
CGContextClipToMask(mainViewContentContext, CGRectMake(0, 0, targetSize.width, targetSize.height), maskImage);
CGContextDrawImage(mainViewContentContext, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), self.CGImage);


// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);

// convert the finished resized image to a UIImage 
UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext];
// image is retained by the property setting above, so we can 
// release the original
CGImageRelease(mainViewContentBitmapContext);

// return the image
return theImage;

回答by Mohammed Afsul

- (UIImage*) maskImage:(UIImage *)image {

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    UIImage *maskImage = [UIImage imageNamed:@"MaskFinal.png"];
    CGImageRef maskImageRef = [maskImage CGImage];

    // create a bitmap graphics context the size of the image
    CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);


    if (mainViewContentContext==NULL)
        return NULL;

    CGFloat ratio = 0;

    ratio = maskImage.size.width/ image.size.width;

    if(ratio * image.size.height < maskImage.size.height) {
        ratio = maskImage.size.height/ image.size.height;
    } 

    CGRect rect1  = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
    CGRect rect2  = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};


    CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
    CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);


    // Create CGImageRef of the main view bitmap content, and then
    // release that bitmap context
    CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
    CGContextRelease(mainViewContentContext);

    UIImage *theImage = [UIImage imageWithCGImage:newImage];

    CGImageRelease(newImage);

    // return the image
    return theImage;
}

回答by Wes Duff

The image to be masked MUST be created with an alpha channel. The Alpha channel may not be created from the code.

要遮罩的图像必须使用 alpha 通道创建。Alpha 通道可能不是从代码创建的。