2014-11-02 130 views
2

我有一个层,我希望用户绘制一个'面具'剪切图像。它是半透明的,所以他们可以看到他们正在选择的东西下面。如何去除不透明度,但保持UIImage的alpha通道?

我该如何处理这个图形数据,其alpha值为1.0,但保留alpha通道(用于掩码)?

TL:DR - 我想让黑色区域成为一种纯色,单色。

  • 下面是之前和之后所希望的(白色背景应该在这两个是透明的): Desired Before & After

是这样的:

for (pixel in image) { 
    if (pixel.alpha != 0.0) { 
    fill solid black 
    } 
} 

回答

2

下应该做什么你”重新过后。大部分代码是从How to set the opacity/alpha of a UIImage?我只是在将像素的颜色转换为黑色之前,为alpha值添加了一个测试。

// Create a pixel buffer in an easy to use format 
CGImageRef imageRef = [[UIImage imageNamed:@"testImage"] CGImage]; 
NSUInteger width = CGImageGetWidth(imageRef); 
NSUInteger height = CGImageGetHeight(imageRef); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

UInt8 * m_PixelBuf = malloc(sizeof(UInt8) * height * width * 4); 

NSUInteger bytesPerPixel = 4; 
NSUInteger bytesPerRow = bytesPerPixel * width; 
NSUInteger bitsPerComponent = 8; 
CGContextRef context = CGBitmapContextCreate(m_PixelBuf, width, height, 
              bitsPerComponent, bytesPerRow, colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
CGContextRelease(context); 

//alter the alpha when the alpha of the source != 0 
int length = height * width * 4; 
for (int i=0; i<length; i+=4) { 
    if (m_PixelBuf[i+3] != 0) { 
    m_PixelBuf[i+3] = 255; 
    } 
} 

//create a new image 
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf, width, height, 
             bitsPerComponent, bytesPerRow, colorSpace, 
             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGImageRef newImgRef = CGBitmapContextCreateImage(ctx); 
CGColorSpaceRelease(colorSpace); 
CGContextRelease(ctx); 
free(m_PixelBuf); 

UIImage *finalImage = [UIImage imageWithCGImage:newImgRef]; 
CGImageRelease(newImgRef); 

finalImage现在将包含一个图像,其中不具有的0.0的α的所有像素具有为1

+0

不错,只需要一个小的调整,使像素黑色: 'for(int i = 0; i Halpo 2014-11-03 07:36:55

+0

有了所有适当的推理,我不认为这种调整原始位图的像素缓冲区的技术是正确的方法。这假设alpha通道简单地反映了线路的不透明性。但是您渲染的路径可能具有消除锯齿的边缘;这种技术将不必要地在面具中引入锯齿。我建议不要像这样编辑像素缓冲区。相反,您想要使用1.0的alpha值重新渲染模型的原始路径。这样,您的面罩将享受边缘的抗锯齿性质,同时使主要行程路径完全不透明。 – Rob 2014-11-03 14:57:46

1

基础模型阿尔法此应用不应图像。这不是一个“如何从另一个图像创建一个图像再现”的问题。

相反,底层对象模型应该是一个路径数组。然后,当你想创建具有半透明路径与不透明路径的图像时,这只是你如何呈现这个路径数组的问题。一旦你解决这个问题,这个问题不是一个复杂的图像处理问题,而是一个简单的渲染问题。

顺便说一下,我真的很喜欢这个路径数组模型,因为这样做会变得相当的微不足道,例如“gee,让我提供一个撤销函数,让用户一次删除一个笔画。它为您打开各种不错的功能增强。

就如何呈现这些路径的具体细节而言,它可以以各种不同的方式实现。您可以使用自定义drawRect函数来呈现具有适当字母的路径的UIView子类。或者您也可以使用CAShapeLayer对象。或者你可以做一些混合(当你完成添加每个路径时创建新的图像快照,避免每次重新渲染所有路径)。有很多方法可以解决这个问题。

但关键的洞察力是采用的路径的数组的底层模型,然后将两种图像的渲染变得相当简单的练习:

pathsmask

第一个图像是渲染一组路径为CAShapeLayer对象,其中alpha为0.5。第二个是相同的渲染,但是具有1.0的alpha。同样,如果使用形状图层或低级别的Core Graphics调用,则无关紧要,但其基本思路是相同的。使用半透明渲染你的路径。

+0

我的应用程序使用路径(与撤消能力等),这只是一个最终的渲染解决方案 – Halpo 2014-11-03 07:38:29

+0

然后我不明白这个问题。两次渲染你的路径以得到两幅图像,一次用alpha少于一次,然后再用alpha等于一。这会产生你需要的两个图像。 – Rob 2014-11-03 13:24:30

相关问题