问题描述
如何提取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通道转换为遮罩?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!