Nice programing

Iphone UIImageView에 애니메이션 GIF 이미지 추가

nicepro 2020. 10. 22. 22:49
반응형

Iphone UIImageView에 애니메이션 GIF 이미지 추가


UIImageview의 URL에서 애니메이션 GIF 이미지를로드해야합니다.

일반 코드를 사용했을 때 이미지가로드되지 않았습니다.

애니메이션 GIF 이미지를로드하는 다른 방법이 있습니까?


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

이것은 수락 된 답변을 찾았지만 최근에 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"]];

마법처럼 작동합니다.


다음은 Gif 이미지를 사용하는 가장 좋은 솔루션입니다. 프로젝트의 Github에서 SDWebImage를 추가합니다.

#import "UIImage+GIF.h"

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

이 링크 확인

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

이것이 도움이되기를 바랍니다.


타사 라이브러리를 사용하지 않으려면

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()
}

.xcassets 폴더가 아닌 프로젝트에 gif 파일을 추가해야합니다.


이것은 UIImageView를 사용하는 요구 사항을 충족하지 않지만 아마도 이것은 당신을 위해 일을 단순화 할 것입니다. UIWebView 사용을 고려해 보셨습니까?

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

원하는 경우 인터넷이 필요한 URL에 연결하는 대신 HTML 파일을 Xcode 프로젝트로 가져 와서 문자열에 루트를 설정할 수 있습니다.


다음은 흥미로운 라이브러리입니다. https://github.com/Flipboard/FLAnimatedImage

데모 예제를 테스트했는데 잘 작동합니다. UIImageView의 자식입니다. 따라서 스토리 보드에서도 직접 사용할 수 있다고 생각합니다.

건배


답변이 이미 승인되었음을 알고 있지만 다른 UIKit Framework 클래스를 사용하는 것처럼 느껴지는 iOS에 Gif 지원을 추가하는 임베디드 프레임 워크를 만들었다는 사실을 공유하려고하지 않습니다.

예를 들면 다음과 같습니다.

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

https://github.com/ObjSal/UIGifImage/releases 에서 최신 릴리스를 다운로드 하십시오.

-살


URL에서 gif 이미지를로드해야하는 경우 항상 .gif 파일의 이미지 태그에 gif를 포함 할 수 있습니다 UIWebView.


SWIFT 3

Swift 버전이 필요한 분들을위한 업데이트입니다!.

A few days ago i needed to do something like this. I load some data from a server according specific parameters and in the meanwhile i wanted to show a different gif image of "loading". I was looking for an option to do it with an UIImageView but unfortunately i didn't find something to do it without splitting the .gif images. So i decided to implement a solution using a UIWebView and i want to shared it:

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)
    }
} 

I made an extension for UIView which adds a UIWebView as subview and displays the .gif images just passing its name.

Now in my UIViewController i have a UIView named 'loadingView' which is my 'loading' indicator and whenever i wanted to show the .gif image, i did something like this:

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
    }
}

when I wanted to change the gif image, simply called the function configureLoadingView() with the name of my new .gif image and calling showLoadingView(), hideLoadingView() properly everything works fine!.

BUT...

... if you have the image splitted then you can animate it in a single line with a UIImage static method called UIImage.animatedImageNamed like this:

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

From the docs:

This method loads a series of files by appending a series of numbers to the base file name provided in the name parameter. All images included in the animated image should share the same size and scale.

Or you can make it with the UIImage.animatedImageWithImages method like this:

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

From the docs:

Creates and returns an animated image from an existing set of images. All images included in the animated image should share the same size and scale.


You Can use 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];

Swift 3:

As suggested above I'm using FLAnimatedImage with an FLAnimatedImageView. And I'm loading the gif as a data set from xcassets. This allows me to provide different gifs for iphone and ipad for appearance and app slicing purposes. This is far more performant than anything else I've tried. It's also easy to pause using .stopAnimating().

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

참고URL : https://stackoverflow.com/questions/4386675/add-animated-gif-image-in-iphone-uiimageview

반응형