【问题标题】:Add animated Gif image in Iphone UIImageView在 Iphone UIImageView 中添加动画 Gif 图像
【发布时间】:2011-05-22 03:54:10
【问题描述】:

我需要从 UIImageview 中的 URL 加载动画 Gif 图像。

当我使用普通代码时,图像没有加载。

还有其他方法可以加载动画 Gif 图像吗?

【问题讨论】:

标签: objective-c iphone uiimageview


【解决方案1】:
UIImageView* animatedImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
animatedImageView.animationImages = [NSArray arrayWithObjects:    
                               [UIImage imageNamed:@"image1.gif"],
                               [UIImage imageNamed:@"image2.gif"],
                               [UIImage imageNamed:@"image3.gif"],
                               [UIImage imageNamed:@"image4.gif"], nil];
animatedImageView.animationDuration = 1.0f;
animatedImageView.animationRepeatCount = 0;
[animatedImageView startAnimating];
[self.view addSubview: animatedImageView];

您可以加载多个 gif 图片。

您可以使用以下ImageMagick 命令拆分您的 gif:

convert +adjoin loading.gif out%d.gif

【讨论】:

  • 我需要从 UIImageview 中的以下 URL 加载图像.... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
  • NSData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myurl]]; UIImage *myimage = [[UIImage alloc] initWithData:imageData];使用它从 url 读取然后将此对象添加到数组
  • iPhone OS 不能也不会正确显示动画 GIF 图像。 UIImage 对象不能用于此。即使它支持 GIF 图像,任何动画都会被丢弃,并且只会显示第一帧。所以,如果你需要在 iPhone 应用程序中显示动画 GIF,那你就完蛋了。代码需要写...看这里:pliep.nl/blog/2009/04/…
  • 你只需要使用网页视图而不是图像视图
  • github.com/mayoff/uiimage-from-animated-gif 只需使用此类别,因为它会自动生成答案中描述的所有内容
【解决方案2】:

这找到了一个公认的答案,但我最近遇到了UIImage+animatedGIF UIImage 扩展。它提供以下类别:

+[UIImage animatedImageWithAnimatedGIFURL:(NSURL *)url]

让你简单地:

#import "UIImage+animatedGIF.h"
UIImage* mygif = [UIImage animatedImageWithAnimatedGIFURL:[NSURL URLWithString:@"http://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif"]];

像魔术一样工作。

【讨论】:

  • 有没有办法直接在项目中使用文件,而不是从 URL 加载 gif?
  • UIImage+animatedGIF...我见过的最好的类别之一...感谢@robmayoff
【解决方案3】:

这是使用 Gif Image 的最佳解决方案。 在您的项目中添加来自 Github 的 SDWebImage。

#import "UIImage+GIF.h"

_imageViewAnimatedGif.image= [UIImage sd_animatedGIFNamed:@"thumbnail"];

【讨论】:

  • 这正是我想要的。谢谢你,兄弟!如果我可以添加一个东西: UIImageView 没有合成,但应该在情节提要中创建并链接到它的 IBOutlet :)
【解决方案4】:

查看此链接

https://github.com/mayoff/uiimage-from-animated-gif/blob/master/uiimage-from-animated-gif/UIImage%2BanimatedGIF.h

并导入这些类 UIImage+animatedGIF.h,UIImage+animatedGIF.m

使用此代码

 NSURL *urlZif = [[NSBundle mainBundle] URLForResource:@"dots64" withExtension:@"gif"];
 NSString *path=[[NSBundle mainBundle]pathForResource:@"bar180" ofType:@"gif"];
 NSURL *url=[[NSURL alloc] initFileURLWithPath:path];
 imageVw.image= [UIImage animatedImageWithAnimatedGIFURL:url];

希望对你有帮助

【讨论】:

    【解决方案5】:

    如果您不想使用 3rd 方库,

    extension UIImageView {
        func setGIFImage(name: String, repeatCount: Int = 0 ) {
            DispatchQueue.global().async {
                if let gif = UIImage.makeGIFFromCollection(name: name, repeatCount: repeatCount) {
                    DispatchQueue.main.async {
                        self.setImage(withGIF: gif)
                        self.startAnimating()
                    }
                }
            }
        }
    
        private func setImage(withGIF gif: GIF) {
            animationImages = gif.images
            animationDuration = gif.durationInSec
            animationRepeatCount = gif.repeatCount
        }
    }
    
    extension UIImage {
        class func makeGIFFromCollection(name: String, repeatCount: Int = 0) -> GIF? {
            guard let path = Bundle.main.path(forResource: name, ofType: "gif") else {
                print("Cannot find a path from the file \"\(name)\"")
                return nil
            }
    
            let url = URL(fileURLWithPath: path)
            let data = try? Data(contentsOf: url)
            guard let d = data else {
                print("Cannot turn image named \"\(name)\" into data")
                return nil
            }
    
            return makeGIFFromData(data: d, repeatCount: repeatCount)
        }
    
        class func makeGIFFromData(data: Data, repeatCount: Int = 0) -> GIF? {
            guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
                print("Source for the image does not exist")
                return nil
            }
    
            let count = CGImageSourceGetCount(source)
            var images = [UIImage]()
            var duration = 0.0
    
            for i in 0..<count {
                if let cgImage = CGImageSourceCreateImageAtIndex(source, i, nil) {
                    let image = UIImage(cgImage: cgImage)
                    images.append(image)
    
                    let delaySeconds = UIImage.delayForImageAtIndex(Int(i),
                                                                    source: source)
                    duration += delaySeconds
                }
            }
    
            return GIF(images: images, durationInSec: duration, repeatCount: repeatCount)
        }
    
        class func delayForImageAtIndex(_ index: Int, source: CGImageSource!) -> Double {
            var delay = 0.0
    
            // Get dictionaries
            let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
            let gifPropertiesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.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
    
            return delay
        }
    }
    
    class GIF: NSObject {
        let images: [UIImage]
        let durationInSec: TimeInterval
        let repeatCount: Int
    
        init(images: [UIImage], durationInSec: TimeInterval, repeatCount: Int = 0) {
            self.images = images
            self.durationInSec = durationInSec
            self.repeatCount = repeatCount
        }
    }
    

    使用,

    override func viewDidLoad() {
        super.viewDidLoad()
        imageView.setGIFImage(name: "gif_file_name")
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        imageView.stopAnimating()
    }
    

    确保将 gif 文件添加到项目中,而不是 .xcassets 文件夹中。

    【讨论】:

    • 您的代码导致:线程 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 错误!
    • 像魅力一样工作。非常感谢。
    【解决方案6】:

    这不符合使用 UIImageView 的要求,但也许这会为您简化事情。您是否考虑过使用 UIWebView?

    NSString *gifUrl = @"http://gifs.com";
    NSURL *url = [NSURL URLWithString: gifUrl];
    [webView loadRequest: [NSURLRequest requestWithURL:url]
    

    如果需要,您可以将 HTML 文件导入 Xcode 项目并在字符串中设置根,而不是链接到需要 Internet 的 URL。

    【讨论】:

      【解决方案7】:

      这是一个有趣的库:https://github.com/Flipboard/FLAnimatedImage

      我测试了演示示例,它运行良好。它是 UIImageView 的孩子。所以我认为你也可以直接在 Storyboard 中使用它。

      干杯

      【讨论】:

        【解决方案8】:

        我知道一个答案已经被批准,但很难不尝试分享我已经创建了一个嵌入式框架,它为 iOS 添加了 Gif 支持,感觉就像你在使用任何其他 UIKit 框架类一样。

        这是一个例子:

        UIGifImage *gif = [[UIGifImage alloc] initWithData:imageData];
        anUiImageView.image = gif;
        

        https://github.com/ObjSal/UIGifImage/releases下载最新版本

        -- 萨尔

        【讨论】:

          【解决方案9】:

          如果您必须从 URL 加载 gif 图片,您可以随时将 gif 嵌入到 UIWebView 中的图片标签中。

          【讨论】:

            【解决方案10】:

            SWIFT 3

            这里是给需要 Swift 版本的人的更新!

            几天前我需要做这样的事情。我根据特定参数从服务器加载一些数据,同时我想显示一个不同的“加载”的 gif 图像。我一直在寻找使用UIImageView 的选项,但不幸的是,如果不拆分 .gif 图像,我找不到可以做的事情。所以我决定使用UIWebView 来实现一个解决方案,我想分享它:

            extension UIView{
                func animateWithGIF(name: String){
                    let htmlString: String =    "<!DOCTYPE html><html><head><title></title></head>" +
                                                    "<body style=\"background-color: transparent;\">" +
                                                        "<img src=\""+name+"\" align=\"middle\" style=\"width:100%;height:100%;\">" +
                                                    "</body>" +
                                                "</html>"
            
                    let path: NSString = Bundle.main.bundlePath as NSString
                    let baseURL: URL = URL(fileURLWithPath: path as String) // to load images just specifying its name without full path
            
                    let frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
                    let gifView = UIWebView(frame: frame)
            
                    gifView.isOpaque = false // The drawing system composites the view normally with other content.
                    gifView.backgroundColor = UIColor.clear
                    gifView.loadHTMLString(htmlString, baseURL: baseURL)
            
                    var s: [UIView] = self.subviews 
                    for i in 0 ..< s.count {
                        if s[i].isKind(of: UIWebView.self) { s[i].removeFromSuperview() }
                    }
            
                    self.addSubview(gifView)
                }
            
                func animateWithGIF(url: String){
                    self.animateWithGIF(name: url)
                }
            } 
            

            我为UIView 做了一个扩展,它添加了一个UIWebView 作为子视图,并显示只是传递其名称的 .gif 图像。

            现在在我的UIViewController 中,我有一个名为“loadingView”的UIView,这是我的“正在加载”指示器,每当我想显示 .gif 图像时,我都会这样做:

            class ViewController: UIViewController {
                @IBOutlet var loadingView: UIView!
            
                override func viewWillAppear(_ animated: Bool) {
                    super.viewWillAppear(animated)
                    configureLoadingView(name: "loading.gif")
                }
            
                override func viewDidLoad() {
                    super.viewDidLoad()
                    // .... some code
                    // show "loading" image
                    showLoadingView()
                }
            
                func showLoadingView(){
                    loadingView.isHidden = false
                }
                func hideLoadingView(){
                    loadingView.isHidden = true
                }
                func configureLoadingView(name: String){
                    loadingView.animateWithGIF(name: "name")// change the image
                }
            }
            

            当我想更改 gif 图像时,只需使用我的新 .g​​if 图像的名称调用函数 configureLoadingView() 并正确调用 showLoadingView()hideLoadingView() 一切正常!

            但是...

            ...如果您将图像拆分,那么您可以使用名为UIImage.animatedImageNamedUIImage 静态方法在一行中对其进行动画处理,如下所示:

            imageView.image = UIImage.animatedImageNamed("imageName", duration: 1.0)

            来自文档:

            此方法通过将一系列数字附加到 name 参数中提供的基本文件名来加载一系列文件。动画图像中包含的所有图像都应具有相同的大小和比例。

            或者您可以使用UIImage.animatedImageWithImages 方法来实现,如下所示:

            let images: [UIImage] = [UIImage(named: "imageName1")!,
                                                        UIImage(named: "imageName2")!,
                                                        ...,
                                                        UIImage(named: "imageNameN")!]
            imageView.image = UIImage.animatedImage(with: images, duration: 1.0)
            

            来自文档:

            从现有图像集创建并返回动画图像。动画图像中包含的所有图像都应具有相同的大小和比例。

            【讨论】:

              【解决方案11】:

              使用 SwiftKingFisher

                 lazy var animatedPart: AnimatedImageView = {
                      let img = AnimatedImageView()
                      if let src = Bundle.main.url(forResource: "xx", withExtension: "gif"){
                          img.kf.setImage(with: src)
                      }
                      return img
                 }()
              

              【讨论】:

                【解决方案12】:

                您可以使用https://github.com/Flipboard/FLAnimatedImage

                #import "FLAnimatedImage.h"
                NSData *dt=[NSData dataWithContentsOfFile:path];
                imageView1 = [[FLAnimatedImageView alloc] init];
                FLAnimatedImage *image1 = [FLAnimatedImage animatedImageWithGIFData:dt];
                imageView1.animatedImage = image1;
                imageView1.frame = CGRectMake(0, 5, 168, 80);
                [self.view addSubview:imageView1];
                

                【讨论】:

                  【解决方案13】:

                  斯威夫特 3:

                  如上所述,我将 FLAnimatedImage 与 FLAnimatedImageView 一起使用。我正在将 gif 作为来自 xcassets 的数据集加载。这使我可以为 iphone 和 ipad 提供不同的 gif,以用于外观和应用程序切片。这比我尝试过的任何其他方法都要高效。使用 .stopAnimating() 也很容易暂停。

                  if let asset = NSDataAsset(name: "animation") {
                      let gifData = asset.data
                      let gif = FLAnimatedImage(animatedGIFData: gifData)
                      imageView.animatedImage = gif
                    }
                  

                  【讨论】:

                    猜你喜欢
                    • 2016-06-04
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-05-13
                    • 2016-05-24
                    • 1970-01-01
                    • 2012-09-03
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多