本文介绍了如何将UIImage / CGImageRef的Alpha通道转换为遮罩?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何提取UIImage或CGImageRef的alpha通道并将其转换为可与CGImageMaskCreate一起使用的蒙版?

How can I extract the alpha channel of a UIImage or CGImageRef and convert it into a mask that I can use with CGImageMaskCreate?

例如:

基本上,给定任何图像,我都不关心图像内的颜色。我要创建的是代表Alpha通道的灰度图像。然后可以使用此图像来遮罩其他图像。

Essentially, given any image, I don't care about the colors inside the image. All I want is to create a grayscale image that represents the alpha channel. This image can then be used to mask other images.

当提供图标图像时,它的示例行为在UIBarButtonItem中。根据Apple文档,它指出:

An example behavior of this is in the UIBarButtonItem when you supply it an icon image. According to the Apple docs it states:

UIBarButtonItem会拍摄任何图像并仅显示

The UIBarButtonItem takes any image and looks only at the alpha, not the colors of the image.

推荐答案

要像按条形按钮项一样对图标上色,您不需要想要传统的蒙版,就需要蒙版的反面-一种蒙版,原始图像中的不透明像素代表最终的颜色,而不是相反。

To color icons the way the bar button items do, you don't want the traditional mask, you want the inverse of a mask-- one where the opaque pixels in the original image take on your final coloring, rather than the other way around.

这是完成此任务的一种方法。取出原始的RBGA图像,并通过以下方式进行处理:

Here's one way to accomplish this. Take your original RBGA image, and process it by:


  • 将其绘制为仅包含Alpha的单通道位图图像

  • 反转每个像素的alpha值以获得与上述相反的行为

  • 将此反转的alpha图像转换为实际的蒙版

  • 使用它。

  • Drawing it into an alpha-only one-channel bitmap image
  • Invert the alpha values of each pixel to get the opposite behavior as noted above
  • Turn this inverted-alpha image into an actual mask
  • Use it.

例如

#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))

// Original RGBA image
CGImageRef originalMaskImage = [[UIImage imageNamed:@"masktest.png"] CGImage];
float width = CGImageGetWidth(originalMaskImage);
float height = CGImageGetHeight(originalMaskImage);

// Make a bitmap context that's only 1 alpha channel
// WARNING: the bytes per row probably needs to be a multiple of 4
int strideLength = ROUND_UP(width * 1, 4);
unsigned char * alphaData = calloc(strideLength * height, sizeof(unsigned char));
CGContextRef alphaOnlyContext = CGBitmapContextCreate(alphaData,
                                                      width,
                                                      height,
                                                      8,
                                                      strideLength,
                                                      NULL,
                                                      kCGImageAlphaOnly);

// Draw the RGBA image into the alpha-only context.
CGContextDrawImage(alphaOnlyContext, CGRectMake(0, 0, width, height), originalMaskImage);

// Walk the pixels and invert the alpha value. This lets you colorize the opaque shapes in the original image.
// If you want to do a traditional mask (where the opaque values block) just get rid of these loops.
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        unsigned char val = alphaData[y*strideLength + x];
        val = 255 - val;
        alphaData[y*strideLength + x] = val;
    }
}

CGImageRef alphaMaskImage = CGBitmapContextCreateImage(alphaOnlyContext);
CGContextRelease(alphaOnlyContext);
free(alphaData);

// Make a mask
CGImageRef finalMaskImage = CGImageMaskCreate(CGImageGetWidth(alphaMaskImage),
                                              CGImageGetHeight(alphaMaskImage),
                                              CGImageGetBitsPerComponent(alphaMaskImage),
                                              CGImageGetBitsPerPixel(alphaMaskImage),
                                              CGImageGetBytesPerRow(alphaMaskImage),
                                              CGImageGetDataProvider(alphaMaskImage), NULL, false);
CGImageRelease(alphaMaskImage);

现在您可以使用 finalMaskImage 作为蒙版了在 CGContextClipToMask 等中,等等。

Now you can use finalMaskImage as the mask in CGContextClipToMask etc, or etc.

这篇关于如何将UIImage / CGImageRef的Alpha通道转换为遮罩?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 14:14
查看更多