美文网首页
关于实现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的动态图片的播放

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