Додайте анімоване зображення GIF в Iphone UIImageView


80

Мені потрібно завантажити анімоване зображення GIF із URL-адреси в UIImageview.

Коли я використовував звичайний код, зображення не завантажувалось.

Чи існує інший спосіб завантаження анімованих зображень у форматі GIF?


мені потрібно завантажити зображення з такої URL-адреси в UIImageview .... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Велмуруган

Пройдіть по цьому посиланню для стрижа: stackoverflow.com/questions/27919620 / ...
Mr.Javed мультані

Відповіді:


138
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.

Ви можете розділити ваш GIF, використовуючи таку команду ImageMagick :

convert +adjoin loading.gif out%d.gif

1
мені потрібно завантажити зображення з такої URL-адреси в UIImageview .... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Велмуруган

NSData * mydata = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: myurl]]; UIImage * myimage = [[UIImage alloc] initWithData: imageData]; використовуйте це для читання з url, а потім додайте цей об'єкт до масиву
Ishu

8
ОС iPhone не може і не відображатиме анімовані зображення GIF належним чином. Для цього не можна використовувати об’єкт UIImage. Незважаючи на те, що він підтримує зображення GIF, будь-яка анімація буде відкинута, а відображатиметься лише перший кадр. Отже, якщо вам потрібно відобразити анімований GIF в додатку для iPhone, ви зіпсуєтесь. Код потрібно написати ... Погляньте тут: pliep.nl/blog/2009/04/…
fyasar

10
Вам просто потрібно використовувати веб-перегляд замість перегляду зображень
Шріш Гарг,

2
github.com/mayoff/uiimage-from-animated-gif просто використовуйте цю категорію, оскільки вона автоматично робить все описане у відповіді
Майкл

53

Це знайшло прийняту відповідь, але нещодавно я натрапив на розширення 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"]];

Працює як магія.


1
Чи був би спосіб використовувати файл безпосередньо в проекті, а не завантажувати gif з URL-адреси?
juliensaad,

2
UIImage + animatedGIF ... одна з найкращих категорій, яку я коли-небудь бачив ... дякую @robmayoff
whyoz

22

Ось найкраще рішення для використання Gif Image. Додайте до свого проекту SDWebImage від Github.

#import "UIImage+GIF.h"

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

ЦЕ саме те, що я шукав. Дякую, чоловіче! Якщо я можу додати щось: UIImageView не синтезується, а повинен бути створений в раскадровці та пов’язаний з його IBOutlet :)
Люсія Белардінеллі

12

Перевірте це посилання

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];

Сподіваюся, це корисно


8

Якщо ви не хочете використовувати сторонні бібліотеки,

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 (код = EXC_I386_INVOP, підкод = 0x0)!
Кодер ACJHP

5

Це не відповідає вимогам використання UIImageView, але, можливо, це спростить для вас речі. Ви розглядали можливість використання UIWebView?

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

Якщо ви хочете, замість посилання на URL-адресу, яка вимагає Інтернету, ви можете імпортувати файл HTML у свій проект Xcode та встановити корінь у рядку.


3

Ось цікава бібліотека: https://github.com/Flipboard/FLAnimatedImage

Я протестував демонстраційний приклад, і він чудово працює. Це дитина UIImageView. Тому я думаю, що ви можете використовувати його безпосередньо у своїй розкадруванні.

Ура


3

Я знаю, що відповідь уже затверджена, але важко не намагатись поділитися тим, що я створив вбудований фреймворк, який додає підтримку Gif для iOS, і це схоже на те, якби ви використовували будь-який інший клас UIKit Framework.

Ось приклад:

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

Завантажте останню версію з https://github.com/ObjSal/UIGifImage/releases

- Сал


1

Якщо вам потрібно завантажити зображення у форматі GIF з URL-адреси, ви завжди можете вставити його у тег зображення в файл UIWebView.


1

SWIFT 3

Ось оновлення для тих, хто потребує версії Swift !.

Кілька днів тому мені потрібно було зробити щось подібне. Я завантажую деякі дані із сервера за певними параметрами, а тим часом хотів показати інше зображення у форматі gif "завантаження". Я шукав варіант зробити це за допомогою, UIImageViewале, на жаль, я не знайшов, чим це зробити, не розділивши зображення .gif. Тому я вирішив застосувати рішення за допомогою a, 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є UIViewіменований 'loadingView', який є моїм показником 'завантаження', і всякий раз, коли я хотів показати зображення .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, просто викликав функцію configureLoadingView()з назвою мого нового зображення .gif та викликаючи showLoadingView(), як hideLoadingView()слід, все працює нормально !.

АЛЕ ...

... якщо у вас зображення розділене, ви можете анімувати його в один рядок за допомогою UIImageстатичного методу, який називається UIImage.animatedImageNamedтак:

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)

З документів:

Створює та повертає анімоване зображення із існуючого набору зображень. Усі зображення, включені в анімоване зображення, мають мати однаковий розмір і масштаб.


0

Ви можете використовувати 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];

0

Свіфт 3:

Як було запропоновано вище, я використовую FLAnimatedImage з FLAnimatedImageView. І я завантажую gif як набір даних із xcassets. Це дозволяє мені надавати різні GIF-файли для iphone та ipad для зовнішнього вигляду та нарізки додатків. Це набагато ефективніше, ніж будь-що інше, що я пробував. Також легко зробити паузу за допомогою .stopAnimating ().

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

0

З Swift та KingFisher

   lazy var animatedPart: AnimatedImageView = {
        let img = AnimatedImageView()
        if let src = Bundle.main.url(forResource: "xx", withExtension: "gif"){
            img.kf.setImage(with: src)
        }
        return img
   }()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.