在iOS中从部分图像创建蒙版

时间:2012-01-31 10:18:52

标签: ios ipad image-processing opengl-es core-graphics

我正在为iPad(iOS4 +)开发着色书应用程序。应用程序应允许一次仅为图像的一个区域着色。

我的意思是,如果用户触摸屏幕上的任何地方并开始移动手指,则颜色应仅应用于与第一个触摸点位于同一区域内的那些像素。例如,如果用户触摸左侧图像的中心并开始在整个图像上移动手指,他应该得到类似右图像的内容。

enter image description here

我认为该任务的解决方案之一可能是创建一个触摸区域形状的蒙版,然后在进行进一步修改之前将此蒙版应用于图像。但是,老实说,我不知道从哪里开始。

请告诉我如何制作这样的面具?

解决方案可能使用Core Graphics和Open GL。

1 个答案:

答案 0 :(得分:2)

正如@Till建议的那样,我实现了排队泛洪填充算法。我必须做some optimizations以将内存消耗和执行速度保持在合理的限度内。

我不使用该算法来真正填充图像。我使用算法创建蒙版:

  • 创建一个掩码字节数组(image_width * image_height字节)
  • 使用0xFF值填充整个数组
  • 使用泛光填充算法查找区域内的所有像素和包含该区域的矩形的坐标。
  • 对于每个找到的像素集,掩码字节数组中的对应值为0
  • 创建另一个(较小的数组)掩码字节,并将掩码字节数组的部分(由计算的矩形定义)复制到新数组。
  • 使用以下代码创建掩码
    NSData* maskData = // construct NSData from mask bytes

    CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFMutableDataRef)maskData);

    int width = maskRight - maskLeft + 1;
    int height = maskBottom - maskTop + 1;
    CGImageRef maskImage = CGImageMaskCreate(width, height, 8, 8, width, dataProvider, NULL, YES);
    CGDataProviderRelease(dataProvider);
  • 您可以稍后使用以下代码
  • 来使用遮罩
    CGContextSaveGState(context);

    CGContextTranslateCTM(context, 0.0, 768);
    CGContextScaleCTM(context, 1.0, -1.0);

    CGRect r = CGRectApplyAffineTransform(maskImageRect, CGContextGetCTM(context));
    CGContextClipToMask(context, r, maskImage);

    CGContextTranslateCTM(context, 0.0, 768);
    CGContextScaleCTM(context, 1.0, -1.0);

    // mask is setup, draw here 

    CGContextRestoreGState(context);

使用此代码,您可以创建任何形状的蒙版。如果需要,您甚至可以创建半透明蒙版。要创建半透明蒙版,您需要在透明区域的掩码字节数组中设置0以外的值(0 - 完全透明,255 - 完全不透明)。