从CALayers绘制图像

时间:2011-01-31 14:43:35

标签: iphone objective-c core-graphics core-animation quartz-graphics

我正在构建某种审查应用程序。到目前为止,我已经完成了用我的iPhone拍摄的图像像素化。

但我想最终实现这样的图像:http://images-mediawiki-sites.thefullwiki.org/11/4/8/8/8328511755287292.jpg

所以我的想法是完全像素化我的图像,然后在它上面添加一个蒙版,以达到预期的效果。因此,就层次而言,它就像:originalImage + maskedPixelatedVersionOfImage ..我正在考虑在触摸图像时为蒙版设置动画,以将蒙版缩放到所需的大小。手指放在图像上的时间越长,面具就越大......

经过一番搜索,我猜这可以使用CALayers和CAAnimation来完成。但是,我如何将这些图层合成到我可以保存在iphone上的photoalbum中的图像?

我在这里采取了正确的方法吗?

编辑:

好吧,我觉得Ole的解决方案是正确的,虽然我仍然没有得到我想要的东西:我使用的代码是:

    CALayer *maskLayer = [CALayer layer];
    CALayer *mosaicLayer = [CALayer layer];

    // Mask image ends with 0.15 opacity on both sides. Set the background color of the layer
    // to the same value so the layer can extend the mask image.
    mosaicLayer.contents = (id)[img CGImage];
    mosaicLayer.frame = CGRectMake(0,0, img.size.width, img.size.height);
    UIImage *maskImg = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mask" ofType:@"png"]];
    maskLayer.contents = (id)[maskImg CGImage];
    maskLayer.frame = CGRectMake(100,150, maskImg.size.width, maskImg.size.height);

    mosaicLayer.mask = maskLayer;

    [imageView.layer addSublayer:mosaicLayer];

    UIGraphicsBeginImageContext(imageView.layer.bounds.size);
    [imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *saver = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

所以在我的imageView中我做了:setImage,它具有照片的原始(未经编辑)版本。最重要的是我添加了一个子图层mosaicLayer,它有一个mask属性:maskLayer。我想通过渲染imageView的rootlayer,一切都会好起来的。这不正确吗?

另外,我想出了别的东西:我的面具被拉伸和旋转,我猜这与imageOrientation有关?我注意到意外地将mosaicLayer保存到我的库中,这也解释了我的问题,即掩码似乎掩盖了我图像的错误部分......

2 个答案:

答案 0 :(得分:7)

要渲染图层树,请将所有图层放在公共容器图层中并调用:

UIGraphicsBeginImageContext(containerLayer.bounds.size);
[containerLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

答案 1 :(得分:4)

如果您愿意放弃对iPhone 3G前设备(iPhone和iPhone 3G)的支持,我建议您使用OpenGL ES 2.0着色器。虽然覆盖包含图像的像素化版本的CALayer可能很容易,但我认为您会发现性能缺乏。

my tests中,对480 x 320图像的每个像素执行简单的基于CPU的计算,导致iPhone 4上的帧速率约为4 FPS。您可能只能采样其中的一小部分像素可以达到预期的效果,但重绘像素化图像以匹配实时视频仍然是一个缓慢的操作。

相反,如果您使用OpenGL ES 2.0片段着色器处理传入的实时视频图像,您应该能够接收原始摄像机图像,有选择地在所需区域上应用此滤镜,并显示或保存结果相机图像。这个处理几乎完全在GPU上进行,我发现它可以在iPhone 4上以60 FPS进行简单的操作。

虽然让片段着色器正常工作可能需要一些设置,但您可以使用this sample application我写的处理相机输入并进行色彩跟踪是一个不错的起点。您还可以查看我在那里使用的触摸手势,其中我将初始触摸点作为居中效果的位置,然后是后续拖动距离以控制效果的强度或半径。