如何删除不透明度但保留UIImage的alpha通道?

时间:2014-11-02 21:36:57

标签: ios uiimage mask blend cgimage

我有一个图层,我希望用户绘制一个'掩码'用于剪切图像。它是半透明的,因此他们可以看到他们正在选择的东西。

如何处理此图形以使绘图数据的alpha值为1.0,但保留alpha通道(用于屏蔽)?

TL:DR - 我希望黑色区域是纯色单色。

  • 这是前后所需的(白色背景应该是透明的): Desired Before & After

类似的东西:

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

2 个答案:

答案 0 :(得分: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的alpha值的像素的alpha值为1。

答案 1 :(得分:1)

此应用的基础模型不应该是图片。这不是&#34;如何从另一个创建图像的一个再现的问题。&#34;

相反,底层对象模型应该是一个路径数组。然后,当你想用半透明路径和不透明路径创建图像时,它只是一个如何渲染这个路径数组的问题。一旦你以这种方式处理它,问题不是一个复杂的图像处理问题,而是一个简单的渲染问题。

顺便说一句,我真的很喜欢这个数组路径模型,因为那样做#34; gee之类的东西变得非常简单,让我提供一个撤销功能,让用户一次删除一个笔划&#34;它为您提供各种功能强大的增强功能。

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

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

paths mask

第一个图像是一堆路径的渲染,CAShapeLayer个对象的alpha为0.5。第二个是相同的渲染,但alpha为1.0。同样,如果您使用形状图层或低级Core Graphics调用并不重要,但基本思想是相同的。要么以半透明的方式呈现你的路径。