我想在 UIView 上创建一个遮罩效果以完成以下操作。我将在屏幕上显示一个密封的盒子,用户将能够触摸(刮擦)屏幕以显示该图像(UIView)背后的内容。类似于那些你想在结果之上刮掉一些封面材料的彩票。
如果有人能指出我正确的方向会很棒,我不知道如何开始这样做......
谢谢
我想在 UIView 上创建一个遮罩效果以完成以下操作。我将在屏幕上显示一个密封的盒子,用户将能够触摸(刮擦)屏幕以显示该图像(UIView)背后的内容。类似于那些你想在结果之上刮掉一些封面材料的彩票。
如果有人能指出我正确的方向会很棒,我不知道如何开始这样做......
谢谢
对不起,我来晚了。我做了一些可能有帮助的示例代码:https ://github.com/oyiptong/CGScratch
drawonward 的方法很有效。
像素编辑通常使用 CGBitmapContext 完成。在这种情况下,我认为您将希望创建一个仅表示暂存区域的 Alpha 通道的灰度位图。当用户划伤时,您将在此位图中进行绘制。
要将 GCBitmapContext 用作图像的遮罩,您必须首先从位图创建遮罩图像。使用 CGImageMaskCreate 并传入指向用于创建位图的相同像素的数据提供程序。然后将 CGImageCreateWithMask 与您的刮擦图像和作为位图的蒙版图像一起使用。
您不能直接在 iPhone 中绘图。每次用户移动手指时,您都必须修改遮罩位图,然后使绘制图像的 UIView 无效。您可能只能再次绘制相同的图像,或者您可能需要在每次绘制时重建蒙版和蒙版图像。只要掩码图像直接引用位图像素数据,实际上分配的内存很少。
所以在伪代码中你想要这样的东西:
scratchableImage = ...
width = CGImageGetWidth( scratchableImage );
height = CGImageGetHeight( scratchableImage );
colorspace = CGColorSpaceCreateDeviceGray();
pixels = CFDataCreateMutable( NULL , width * height );
bitmap = CFBitmapContextCreate( CFDataGetMutableBytePtr( pixels ) , width , height , 8 , width , colorspace , kCGImageAlphaNone );
provider = CGDataProviderCreateWithCFData( pixels );
mask = CGImageMaskCreate( width , height , 8 , 8 , width , provider , NULL , false , kCGRenderingIntentDefault );
scratched = CGImageCreateWithImageInRect( scratchableImage , mask );
此时,scratched
将有一个 alpha 通道,bitmap
但bitmap
有垃圾数据。位图中的白色pixels
不透明,黑色像素清晰。bitmap
然后在用户划痕时绘制所有白色像素,然后绘制黑色像素。我认为bitmap
每次scratched
绘制时都会自动应用更改,但如果不是,那么每次绘制时都重新mask
创建scratched
。
您可能有一个用于跟踪用户输入的自定义 UIView。您可以从 UIImageView 派生您的自定义视图并让它绘制图像或执行以下操作:
-(void) drawRect:(CGRect)inDirty {
// assume scratched is a member
CGContextDrawImage( UIGraphicsGetCurrentContext() , [self bounds] , scratched );
}
或者,您可以跳过创建scratched
,而是直接使用CGContextClipToMask
和绘制原件scratchableImage
。如果没有scratchableImage
,并且您的暂存区域是纹理或视图层次结构,请采用这种方法。