美文网首页
关于实现Image的动态图片的播放

关于实现Image的动态图片的播放

作者: 海笙樾 | 来源:发表于2018-03-22 14:28 被阅读0次

最近在写Swift的时候,需要有一个动态播放头像的功能,于是就自己试着写了个。

这个需要继承UIImage,重写它的方法,全部代码直接贴上去

//

//  UIImageGIF.swift

//  SwiftYiRen

//

//  Created by 李文强 on 2017/11/1.

//  Copyright © 2017年 李文强. All rights reserved.

//

import UIKit

import ImageIO

extension UIImageView{

    public func loadGif(name: String) {

        DispatchQueue.global().async {

            let image = UIImage.gif(name: name)

            DispatchQueue.main.async {

                self.image = image

            }

        }

    }

}

extension UIImage {

    public class func gif(data: Data) -> UIImage? {

        // Create source from data

        guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {

            print("SwiftGif: Source for the image does not exist")

            return nil

        }

        return UIImage.animatedImageWithSource(source)

    }

    public class func gif(url: String) -> UIImage? {

        guard let bundleURL = URL(string: url) else {

            print("SwiftGif: This image named \"\(url)\" does not exist")

            return nil

        }

        guard let imageData = try? Data(contentsOf: bundleURL) else {

            print("SwiftGif: Cannot turn image named \"\(url)\" into NSData")

            return nil

        }

        return gif(data: imageData)

    }

    public class func gif(name: String) -> UIImage? {

        guard let bundleURL = Bundle.main

            .url(forResource: name, withExtension: "gif") else {

                print("SwiftGif: This image named \"\(name)\" does not exist")

                return nil

        }

        // Validate data

        guard let imageData = try? Data(contentsOf: bundleURL) else {

            print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")

            return nil

        }

        return gif(data: imageData)

    }

    internal class func delayForImageAtIndex(_ index: Int, source: CGImageSource!) -> Double {

        var delay = 0.1

        let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)

        let gifPropertiesPointer = UnsafeMutablePointer.allocate(capacity: 0)

        if CFDictionaryGetValueIfPresent(cfProperties, Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque(), gifPropertiesPointer) == false {

            return delay

        }

        let gifProperties:CFDictionary = unsafeBitCast(gifPropertiesPointer.pointee, to: CFDictionary.self)

        // Get delay time

        var delayObject: AnyObject = unsafeBitCast(

            CFDictionaryGetValue(gifProperties,

                                 Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()),

            to: AnyObject.self)

        if delayObject.doubleValue == 0 {

            delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,

                                                             Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self)

        }

        delay = delayObject as? Double ?? 0

        if delay < 0.1 {

            delay = 0.1 // Make sure they're not too fast

        }

        return delay

    }

    internal class func gcdForPair(_ a: Int?, _ b: Int?) -> Int {

        var a = a

        var b = b

        // Check if one of them is nil

        if b == nil || a == nil {

            if b != nil {

                return b!

            } else if a != nil {

                return a!

            } else {

                return 0

            }

        }

        // Swap for modulo

        if a! < b! {

            let c = a

            a = b

            b = c

        }

        // Get greatest common divisor

        var rest: Int

        while true {

            rest = a! % b!

            if rest == 0 {

                return b! // Found it

            } else {

                a = b

                b = rest

            }

        }

    }

    internal class func gcdForArray(_ array: Array) -> Int {

        if array.isEmpty {

            return 1

        }

        var gcd = array[0]

        for val in array {

            gcd = UIImage.gcdForPair(val, gcd)

        }

        return gcd

    }

    internal class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? {

        let count = CGImageSourceGetCount(source)

        var images = [CGImage]()

        var delays = [Int]()

        for i in 0..

            // 添加图片

            if let image = CGImageSourceCreateImageAtIndex(source, i, nil) {

                images.append(image)

            }

                        let delaySeconds = UIImage.delayForImageAtIndex(Int(i),

                                                            source: source)

            delays.append(Int(delaySeconds * 1000.0)) // Seconds to ms

        }

        // Calculate full duration

        let duration: Int = {

            var sum = 0

            for val: Int in delays {

                sum += val

            }

            return sum

        }()

        // Get frames

        let gcd = gcdForArray(delays)

        var frames = [UIImage]()

        var frame: UIImage

        var frameCount: Int

        for i in 0..

            frame = UIImage(cgImage: images[Int(i)])

            frameCount = Int(delays[Int(i)] / gcd)

            for _ in 0..

                frames.append(frame)

            }

        }

        let animation = UIImage.animatedImage(with: frames,

                                              duration: Double(duration) / 1000.0)

        return animation

    }

}

使用

    //头像

    var myHeaderImage:UIImageView = {

        let image = UIImageView.init(frame: CGRect(x:0,y:0,width:80,height:80))

        image.backgroundColor = UIColor.blue

        image.layer.cornerRadius = 40

        image.image = UIImage.gif(name:"GIF图片名(自己工程里的)")

        image.layer.masksToBounds = true

        return image

    }()

相关文章

  • 关于实现Image的动态图片的播放

    最近在写Swift的时候,需要有一个动态播放头像的功能,于是就自己试着写了个。 这个需要继承UIImage,重写它...

  • 2021-03-24

    简单实现基于IOS的音乐播放器,并且带有歌词,随播放自动滚动,实现效果如下: [图片上传失败...(image-8...

  • 收集一些Android常用的功能库(不定期更新)

    实现控件的各种阴影效果image.png 实时显示音乐播放频率的控件image.png 实时显示音乐播放频率的控件...

  • Golang标准库——image

    image image实现了基本的2D图片库。基本接口叫作Image。图片的色彩定义在image/color包。I...

  • Vue实现图片预加载

    实现图片的预加载,其实就是用js创建Image对象,然后绑定Image对象的src属性到图片路径,让其实现加载,这...

  • 图片和视频互转

    -r 指定图片转换帧率 -f 我要将输入文件转成什么格式 image2 就是图片 image开头-%3d 就是动态...

  • 逐步解决动态规划之01背包问题

    [站外图片上传中...(image-fe2902-1583294261806)] 什么是动态规划? 动态规划(Dy...

  • background-image透明,背景图片透明

    关于实现background-image透明,背景图片透明的方法,我查阅了很多资料,然后还是没有解决,这样我们不如...

  • 播放动态图片gif

    1、播放多张静态图片 需要多张连续的静态图片,这个最占内存,不建议用这种原生的,可以考虑第三方 其他操作 2、UI...

  • iOS播放动态gif图片

      图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在Ap...

网友评论

      本文标题:关于实现Image的动态图片的播放

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