分分钟消除马赛克

作者: dimsky | 来源:发表于2016-08-15 00:44 被阅读1953次

    先看图:

    这不是马蓉,跟宝宝也没关系

    无标题,不简书。

    苹果在开发框架中并没有给我们提供太多的图形处理API,模糊效果也只提供了高斯模糊,而且还有使用的限制。如果需要简单的实现其他的模糊效果,我们需要用到一些第三方框架。
    下面我们会用到GPUImage, 这个库有什么用呢?
    在iOS 中,GPUImage是目前做图片、相机滤镜最主流的框架,没有之一,还支持照相机和摄像机的实时滤镜,它基于OpenGL对图片处理单元进行封装,通过GPU进行图形加速处理,所以使用GPUImage 也是让你的应用保持60帧必不可少的,GPUImage还提供了非常多的常用的滤镜,使用也特别简单。也就是说GPUImage能带你玩转所有的图像处理,你可以通过GPUImage 实现很多炫酷的效果。今年很火的Prisma 肯定都用过了,目测也是通过GPUImage来实现。

    GPUImage

    这里介绍一下GPUImage的基本概念:
    GPUImageInput 输入源
    GPUImageOutput 输出源
    GPUImageFilter 滤镜 可以是输出源,也可以是输入源

    图片处理生成就像一根管道,类似这样:

    摘自网络

    在处理过程中,可以添加多个滤镜进行图形处理。

    简单的实现流程是先通过 GPUImagePicture 对象作为输入源传给 GPUImageFilter,然后filter将处理好的图像传给 GPUImageView 最终显示到设备上。
    在加入滤镜修改滤镜的属性之后,我们需要调用processImage 来抓取处理过的图像呈现出来。

    let gpuImagePic = GPUImagePicture(image: image)
    let filter = GPUImagePixellateFilter()
    let gpuImageView = GPUImageView()
    filter.addTarget(gpuImageView)
    filter.forceProcessingAtSize(image!.size)
    filter.fractionalWidthOfAPixel = 0.1
    filter.useNextFrameForImageCapture()
    gpuImagePic.addTarget(filter)
    gpuImagePic.processImage()
    self.view.addSubview(gpuImageView)
    

    CADisplayLink

    然后就是动画了,这里用到了CADisplayLink,CADisplayLink也可以说是一个定时器。因为CADisplayLink可以保证与屏幕刷新率相同的频率,目前主流屏幕都是60Hz,也就是60帧/秒。如果应用的运行帧能达到60帧/秒,那就是如丝般顺滑了。(现在有些高端显示屏幕刷新率也达到了144Hz)。既然使用了GPUImage,那当然不用担心性能了,GPU的图像处理效率比CPU自然高很多。
    CADisplayLink 需要加入到Runloop中使用,通过 paused 属性来控制开始,暂停。

    let displayLink = CADisplayLink(target: self, selector: #selector(transition(_:)))
    displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
    displayLink.paused = true
    

    然后将每一帧都生成图像,通过调用 processImage() 显示出来:

    func transition(link: CADisplayLink) {
        if startTime == 0 {
            startTime = link.timestamp
        }
        progress = max(0, min(CGFloat(link.timestamp - startTime) / duration, 1))
        if isShow {
            filter.fractionalWidthOfAPixel = 0.1 * (1 - progress)
        } else {
            filter.fractionalWidthOfAPixel = 0.1 * progress
        }
        gpuImagePic.processImage()
        if progress == 1 {
            displayLink.paused = true
        }
    }
    

    然后,你就多了一个可已看透马赛克的技能了。恭喜。

    还有,大家觉得马赛克可逆么?

    文中的例子可以在这里下载到。

    相关文章

      网友评论

        本文标题:分分钟消除马赛克

        本文链接:https://www.haomeiwen.com/subject/yffusttx.html