是否可以使CGContextClipToMask
忽略蒙版图像的灰度值,并将其视为纯黑色和白色?
我有一个灰度图像,当我用它作为遮罩时,灰色会被解释为alpha通道。这很好,除了我需要完全掩盖那些不透明的像素。
简短的例子:
UIImage *mask = [self prepareMaskImage];
UIGraphicsBeginImageContextWithOptions(mask.size, NO, mask.scale); {
// Custom code
CGContextClipToMask(UIGraphicsGetCurrentContext(), mask.size, mask.CGImage);
// Custom code
}
是否可以调整此代码以实现我的目标?
长话短说:我需要让透明的灰度图像在最初的位置变得透明,在纯色的地方变成完全黑色。
答案 0 :(得分:1)
我的粗略想法如下:
要简化访问,请使用
typedef struct RGBA {
UInt8 red;
UInt8 green;
UInt8 blue;
UInt8 alpha;
} RGBA;
我们假设image
您的输入掩码。
// First step, using RGBA (because I know it works and does not harm, just writes/consumes twice the amount of memory)
CGImageRef imageRef = image.CGImage;
NSInteger rawWidth = CGImageGetWidth(imageRef);
NSInteger rawHeight = CGImageGetHeight(imageRef);
NSInteger rawBitsPerComponent = 8;
NSInteger rawBytesPerPixel = 4;
NSInteger rawBytesPerRow = rawBytesPerPixel * rawWidth;
CGRect rawRect = CGRectMake(0, 0, rawWidth, rawHeight);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UInt8 *rawImage = (UInt8 *)malloc(rawHeight * rawWidth * rawBytesPerPixel);
CGContextRef rawContext = CGBitmapContextCreate(rawImage,
rawWidth,
rawHeight,
rawBitsPerComponent,
rawBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
// At this point, rawContext is ready for drawing, everything drawn will be in rawImage's byte array.
CGContextDrawImage(rawContext, rawRect, imageRef);
// Second step, crawl the byte array and do the evil work:
for (NSInteger y = 0; y < rawHeight; ++y) {
for (NSInteger x = 0; x < rawWidth; ++x) {
UInt8 *address = rawImage + x * rawBytesPerPixel + y * rawBytesPerRow;
RGBA *pixel = (RGBA *)address;
// If it is a grey input image, it does not matter what RGB channel to use - they shall all be the same
if (0 != pixel->red) {
pixel->alpha = 0;
} else {
pixel->alpha = UINT8_MAX;
}
pixel->red = 0;
pixel->green = 0;
pixel->blue = 0;
// I am still not sure if this is the transformation you are searching for, but it may give you the idea.
}
}
// Third: rawContext is ready, transformation is done. Get the image out of it
CGImageRef outputImage1 = CGBitmapContextCreateImage(rawContext);
UIImage *outputImage2 = [UIImage imageWithCGImage:outputImage1];
CGImageRelease(outputImage1);
好的......输出是RGBA,但你可以创建一个灰度+ alpha上下文,然后在那里blit你的图像进行转换。
答案 1 :(得分:1)
有趣的问题! Here's code在一个简单的示例项目中执行我认为您想要的内容。与上述类似,但正确处理比例。如果需要,还可以选择在蒙版图像中保留alpha。快速黑客攻击测试似乎有效。
答案 2 :(得分:0)
这段代码帮助我在图像的非透明区域上应用色调。
- (UIImage*)imageWithImage:(UIImageView*)source colorValue:(CGFloat)hue {
CGSize imageSize = [source.image size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);
// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
[source.image drawAtPoint:CGPointMake(0, 0)];
// Setup a clip region using the image
CGContextSaveGState(context);
CGContextClipToMask(context, source.bounds, source.image.CGImage);
self.imageColor = [UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:1.0];
[self.imageColor set];
CGContextFillRect(context, source.bounds);
// Draw the hue on top of the image.
CGContextSetBlendMode(context, kCGBlendModeHue);
[self.imageColor set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];
CGContextRestoreGState(context); // remove clip region
// Retrieve the new image.
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}