在视图上创建遮罩效果

发布于 2024-09-05 03:39:33 字数 165 浏览 8 评论 0原文

我想在 UIView 上创建遮罩效果以完成以下任务。我将在屏幕上显示一个密封的盒子,用户将能够触摸(刮擦)屏幕以显示该图像(UIView)后面的内容。类似于那些彩票,你应该在结果之上刮掉一些封面材料。

如果有人能给我指出正确的方向,那就太棒了,我不知道如何开始这样做......

谢谢

I would like to create a masking effect over a UIView in order to accomplish the following. I will display a sealed box in the screen and the user will be able to touch (scratch) the screen in order to reveal whats behind that image(UIView). Something similar to those lottery tickets where u r suppose to scratch some cover material thats on top of the results..

If someone could point me in the right direction would be awesome, I'm not sure how to start doing this...

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

韬韬不绝 2024-09-12 03:39:34

抱歉我来晚了。我制作了一些可能有帮助的示例代码:https://github.com/oyiptong/CGScratch

drawonward's方法有效。

Sorry I'm late. I made some example code which might be of help: https://github.com/oyiptong/CGScratch

drawnonward's approach works.

高速公鹿 2024-09-12 03:39:34

像素编辑通常使用 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 将具有由 bitmap 指定的 Alpha 通道,但 bitmap 包含垃圾数据。位图中的白色像素是不透明的,黑色像素是透明的。在位图中绘制所有白色像素,然后当用户刮擦时绘制黑色像素。我认为每次绘制 scratched 时都会自动应用对 bitmap 的更改,但如果不是,则只需重新创建 maskscratched代码> 每次绘制时。

您可能有一个自定义 UIView 来跟踪用户输入。您可以从 UIImageView 派生自定义视图并让它绘制图像或执行以下操作:

-(void) drawRect:(CGRect)inDirty {
  // assume scratched is a member
  CGContextDrawImage( UIGraphicsGetCurrentContext() , [self bounds] , scratched );
}

或者,您可以跳过创建 scratched ,而是使用 CGContextClipToMask 并绘制原始 直接scratchableImage。如果没有 scratchableImage 并且您的暂存区域是纹理或视图层次结构,请采用此方法。

Pixel editing is usually done with a CGBitmapContext. In this case, I think you will want to create a grayscale bitmap that represents just the alpha channel of the scratch area. As the user scratches, you will paint in this bitmap.

To use a GCBitmapContext as the mask for an image, you must first create a masking image from the bitmap. Use CGImageMaskCreate and pass in a data provider that points to the same pixels used to create the bitmap. Then use CGImageCreateWithMask with your scratch off image and the mask image that is the bitmap.

You cannot draw directly in the iPhone. Every time the user moves a finger, you will have to modify the mask bitmap then invalidate the UIView that draws the image. You may just be able to draw the same image again, or you may need to reconstruct the mask and masked image each time you draw. As long as the mask image refers directly to the bitmap pixel data, very little memory is actually allocated.

So in psuedocode you want something like this:

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 );

At this point, scratched will have an alpha channel dictated by bitmap but bitmap has garbage data. White pixels in bitmap are opaque, and black pixels are clear. Paint all white pixels in bitmap then, as the user scratches, paint black pixels. I think that changes to bitmap will automatically apply every time scratched is drawn, but if not then just recreate mask and scratched every time you draw.

You probably have a custom UIView for tracking user input. You could derive your custom view from UIImageView and let it draw the image or do the following:

-(void) drawRect:(CGRect)inDirty {
  // assume scratched is a member
  CGContextDrawImage( UIGraphicsGetCurrentContext() , [self bounds] , scratched );
}

Alternately you can skip creating scratched and instead use CGContextClipToMask and draw the original scratchableImage directly. If there is no scratchableImage and your scratch area is a texture or view hierarchy, take this approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文