所以我尝试使用 Quartz CGImageCreateWithMaskingColors 函数,但他唯一的问题是它掩盖了您选择的颜色范围。
我想屏蔽除我选择的颜色范围之外的所有内容。例如,我想在图片中显示所有红色,但删除其他通道(绿色和蓝色)。
我在 Objective-C 中这样做,我是一个菜鸟,所以请给我例子:)
任何帮助是极大的赞赏。
所以我尝试使用 Quartz CGImageCreateWithMaskingColors 函数,但他唯一的问题是它掩盖了您选择的颜色范围。
我想屏蔽除我选择的颜色范围之外的所有内容。例如,我想在图片中显示所有红色,但删除其他通道(绿色和蓝色)。
我在 Objective-C 中这样做,我是一个菜鸟,所以请给我例子:)
任何帮助是极大的赞赏。
使用这些方法。我在其中一篇 SO 帖子中找到了它们。
-(void)changeColor
{
UIImage *temp23=Image;//Pass your image here
CGImageRef ref1=[self createMask:temp23];
const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
UIImage *resultedimage=[UIImage imageWithCGImage:New];
EditImageView.image = resultedimage;
[EditImageView setNeedsDisplay];
}
-(CGImageRef)createMask:(UIImage*)temp
{
CGImageRef ref=temp.CGImage;
int mWidth=CGImageGetWidth(ref);
int mHeight=CGImageGetHeight(ref);
int count=mWidth*mHeight*4;
void *bufferdata=malloc(count);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4, colorSpaceRef, kCGImageAlphaPremultipliedFirst);
CGRect rect = {0,0,mWidth,mHeight};
CGContextDrawImage(cgctx, rect, ref);
bufferdata = CGBitmapContextGetData (cgctx);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bufferdata, mWidth*mHeight*4, NULL);
CGImageRef savedimageref = CGImageCreate(mWidth,mHeight, 8, 32, mWidth*4, colorSpaceRef, bitmapInfo,provider , NULL, NO, renderingIntent);
CFRelease(colorSpaceRef);
return savedimageref;
}
然后在按钮单击事件上调用 changecolor 方法并查看结果
我找到了上述问题的答案,按照上面的 Rahul 代码进行一些更改以设置自己的颜色,
-(void)changeColor
{
UIImage *temp23=Image;//Pass your image here
CGImageRef ref1=[self createMask:temp23];
const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
UIImage *resultedimage=[UIImage imageWithCGImage:New];
EditImageView.image = resultedimage;
[EditImageView setNeedsDisplay];
}
-(CGImageRef)createMask:(UIImage*)temp
{
CGImageRef ref=temp.CGImage;
int mWidth=CGImageGetWidth(ref);
int mHeight=CGImageGetHeight(ref);
int count=mWidth*mHeight*4;
void *bufferdata=malloc(count);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4,colorSpaceRef, kCGImageAlphaPremultipliedLast);
CGRect rect = {0,0,mWidth,mHeight};
CGContextDrawImage(cgctx, rect, ref);
CGContextSaveGState(cgctx);
CGContextSetBlendMode(cgctx, kCGBlendModeColor);
CGContextSetRGBFillColor (cgctx, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(cgctx, rect);
bufferdata = CGBitmapContextGetData (cgctx);
const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bufferdata, mWidth*mHeight*4, NULL);
CGImageRef savedimageref = CGImageCreate(mWidth,mHeight, 8, 32, mWidth*4, colorSpaceRef, bitmapInfo,provider , NULL, NO, renderingIntent);
CFRelease(colorSpaceRef);
return savedimageref;
}
嗯……
我可能遗漏了一些东西,但我不相信提供的答案适用于该问题。第二个响应更接近标记,但它包含与解决方案无关的虚假代码。
该createMask
方法制作原始图像的副本,假设 alpha 在 LSB 位置。changeColor 执行一个对 RGB 图像没有太大作用的掩码调用——基本上只有黑色会被掩码(即,(1,1,2) 到 (3, 2,1))。
我猜正在观察到的红移是由于参数
kCGImageAlphaPremultipliedFirst
在行中
CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4, colorSpaceRef, kCGImageAlphaPremultipliedFirst);
由于 alpha 通道处理不当。如果在changeColor
方法中您修改了块
CGImageRef ref1=[self createMask:temp23];
const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
UIImage *resultedimage=[UIImage imageWithCGImage:New];
EditImageView.image = resultedimage;
成为
CGImageRef ref1=[self createMask:temp23];
UIImage *resultedimage=[UIImage imageWithCGImage:ref];
EditImageView.image = resultedimage;
你会看到显示没有区别。将 CGBitmapInfo 常量更改为kCGImageAlphaPremultipliedLast
应该使用上述任一代码块正确显示图像。
下一个响应更接近 OP 的要求,但它是在视觉效果方面,而不是实际数据。这里的相关代码createMask
是
CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4,colorSpaceRef, kCGImageAlphaPremultipliedLast);
正确显示图像,然后是
CGContextSetBlendMode(cgctx, kCGBlendModeColor);
CGContextSetRGBFillColor (cgctx, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(cgctx, rect);
然后是构建图像的逻辑。混合逻辑在原始图像上覆盖红色色调,实现与原始响应中放错位置的 Alpha 通道类似的效果。这仍然不是 OP 所要求的,即掩盖一个或多个通道,而不是混合颜色。
这实际上相当于将不需要的颜色的通道值设置为零。这是一个仅返回红色通道作为 OP 请求的示例;假设像素的格式是 ABGR:
- (CGImageRef) redChannel:(CGImageRef)image
{
CGDataProviderRef provider = CGImageGetDataProvider(image);
NSMutableData* data = (id)CGDataProviderCopyData(provider);
int width = CGImageGetWidth(image);
int height = CGImageGetHeight(image);
[data autorelease];
// get a mutable reference to the image data
uint32_t* dwords = [data mutableBytes];
for (size_t idx = 0; idx < width*height; idx++) {
uint32_t* pixel = &dwords[idx];
// perform a logical AND of the pixel with a mask that zeroes out green and blue pixels
*pixel &= 0x000000ff;
}
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// now create a new image using the masked original data
CGDataProviderRef iprovider = CGDataProviderCreateWithData(NULL, dwords, width*height*4, NULL);
CGImageRef savedimageref = CGImageCreate(width, height, 8, 32, width*4, colorSpaceRef, bitmapInfo, iprovider, NULL, NO, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(iprovider);
return savedimageref;
}
可以在这里找到按位运算的一个很好的总结。
正如这里所指出的,您可能需要根据像素中位的 LSB/MSB 排序来更改掩码的结构。此示例假定标准 iPhone PNG 的 32 位像素。