知道为什么这个图像掩盖代码不起作用?

Tha*_*nks 10 iphone cocoa-touch image-manipulation core-graphics uikit

我有这个代码来掩盖图像.基本上,我只使用PNG图像.所以我有一个300x400的PNG图像,24位色(PNG-24).我不确定它是否也有alpha通道.但它没有透明度.

然后,有没有alpha通道的PNG-8bit的图像掩码.它只是黑色,灰度和白色.

我创建了两个图像作为UIImage.将它们放入UIImageView时,两者都能正确显示.

然后我创建了一个UIImage,它包含了掩码操作的结果,使用以下代码:

+ (UIImage*)maskImage:(UIImage*)image withMask:(UIImage*)maskImage {
 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);
 return [UIImage imageWithCGImage:masked];
}
Run Code Online (Sandbox Code Playgroud)

这就是我用它做的事情:

 UIImage *image = [UIImage imageNamed:@"coloredImagePNG24.png"];
 UIImage *maskImage = [UIImage imageNamed:@"theMaskPNG8_Grayscale_NoAlpha.png"];
 UIImage *maskedImage = [MyGraphicUtils maskImage:image withMask:maskImage];
 UIImageView *testImageView = [[UIImageView alloc] initWithImage:maskedImage];
 testImageView.backgroundColor = [UIColor clearColor];
 testImageView.opaque = NO;
Run Code Online (Sandbox Code Playgroud)

毕竟,coloredImagePNG24.png保持原样完好无损.没有掩盖正在发生.但现在奇怪的是:如果我把它转过来,即使用这个图像作为蒙版,并将蒙版作为彩色图像到蒙版,那么我会得到灰度非常难看的东西(但是蒙版;)).

知道我的代码有什么问题吗?

更新:我只是用谷歌搜索一个不同的黑白png用它作为掩码.然后这个工作了!但我自己制作的那个不起作用.所以我假设代码有很大的图像解码问题.我必须将图像"规范化"为特定格式,以便它可以工作.

Sha*_*a G 6

此代码可能对您有所帮助

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

    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);
    return [UIImage imageWithCGImage:masked];

}
Run Code Online (Sandbox Code Playgroud)

参考这个示例演示

  • 只要使用UIImageView显示生成的UIImage或手动绘制到新的图像上下文中,这就可以工作.如果您尝试使用UIImagePNGRepresentation(yourMaskedImage)将图像保存到文件,则会丢失蒙版.仅供参考 - 我正在把头发拉过来一点.在代码的最后,你应该发布一些引用来避免内存泄漏:CGImageRelease(maskedImageRef); CGImageRelease(掩模); (7认同)

bun*_*ero 5

正如您所发现的,保存文件的方式可能会有所不同,因为Core Graphics非常关注它用于屏蔽的位的格式.

我发现从任意图像生成图像蒙版的最佳和最可靠的方法是这样做:

  1. 创建一个可接受的图像掩码格式的位图图形上下文(你不能使用UIGraphicsBeginImageContext())
  2. 将图像绘制到此位图图形上下文中
  3. 从位图图形上下文的位创建图像蒙版.

试试这个功能:

CGImageRef createMaskWithImage(CGImageRef image)
{
    int maskWidth               = CGImageGetWidth(image);
    int maskHeight              = CGImageGetHeight(image);
    //  round bytesPerRow to the nearest 16 bytes, for performance's sake
    int bytesPerRow             = (maskWidth + 15) & 0xfffffff0;
    int bufferSize              = bytesPerRow * maskHeight;

    //  allocate memory for the bits 
    CFMutableDataRef dataBuffer = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CFDataSetLength(dataBuffer, bufferSize);

    //  the data will be 8 bits per pixel, no alpha
    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef ctx            = CGBitmapContextCreate(CFDataGetMutableBytePtr(dataBuffer),
                                                        maskWidth, maskHeight,
                                                        8, bytesPerRow, colourSpace, kCGImageAlphaNone);
    //  drawing into this context will draw into the dataBuffer.
    CGContextDrawImage(ctx, CGRectMake(0, 0, maskWidth, maskHeight), image);
    CGContextRelease(ctx);

    //  now make a mask from the data.
    CGDataProviderRef dataProvider  = CGDataProviderCreateWithCFData(dataBuffer);
    CGImageRef mask                 = CGImageMaskCreate(maskWidth, maskHeight, 8, 8, bytesPerRow,
                                                        dataProvider, NULL, FALSE);

    CGDataProviderRelease(dataProvider);
    CGColorSpaceRelease(colourSpace);
    CFRelease(dataBuffer);

    return mask;
}
Run Code Online (Sandbox Code Playgroud)


Ram*_*min 0

看看这样是否效果更好:

+ (UIImage*)maskImage:(UIImage*)image withMask:(UIImage*)maskImage {
   UIGraphicsBeginImageContext(image.size);
   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* result = [UIImage imageWithData:UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext())];
   UIGraphicsEndImageContext();
   CGImageRelease(mask);
   CGImageRelease(masked);
   return result;
}
Run Code Online (Sandbox Code Playgroud)