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


80

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

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

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


내가있는 UIImageView ....에서 다음 URL에서 이미지를로드 할 필요 feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Velmurugan

: SWIFT이 링크를 통해 이동 stackoverflow.com/questions/27919620/...
Mr.Javed Multani

답변:


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 이미지를로드 할 수 있습니다.

다음 ImageMagick 명령을 사용하여 gif를 분할 할 수 있습니다 .

convert +adjoin loading.gif out%d.gif

1
내가있는 UIImageView ....에서 다음 URL에서 이미지를로드 할 필요 feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Velmurugan

NSData * mydata = [[NSData 할당] initWithContentsOfURL : [NSURL URLWithString : myurl]]; UIImage * myimage = [[UIImage 할당] initWithData : imageData]; URL에서 읽기 위해 이것을 사용하고 배열에이 객체를 추가합니다
Ishu

8
iPhone OS는 애니메이션 GIF 이미지를 제대로 표시 할 수 없으며 표시하지 않습니다. 이를 위해 UIImage 객체를 사용할 수 없습니다. GIF 이미지를 지원하더라도 모든 애니메이션이 삭제되고 첫 번째 프레임 만 표시됩니다. 따라서 iPhone 앱 내부에 애니메이션 GIF를 표시해야하는 경우 문제가 발생합니다. 코드를 작성해야합니다 ... 여기를보세요 : pliep.nl/blog/2009/04/…
fyasar

10
당신은 대신 이미지 뷰의 웹보기를 사용해야합니다
Shreesh Garg를

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
URL에서 gif를로드하는 대신 프로젝트에서 직접 파일을 사용하는 방법이 있습니까?
juliensaad 2014-06-11

2
UIImage + animatedGIF ... 내가 본 최고의 카테고리 중 하나 ... 감사합니다 @robmayoff
whyoz

22

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

#import "UIImage+GIF.h"

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

이것이 바로 제가 찾던 것입니다. 고마워요! 추가 할 수있는 경우 : UIImageView는
신테 이즈

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

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


귀하의 코드는 다음과 같습니다 : 스레드 1 : EXC_BAD_INSTRUCTION (코드 = EXC_I386_INVOP, 하위 코드 = 0x0) 오류!
Coder ACJHP

5

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

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

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



3

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

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

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

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

-살


1

URL에서 gif 이미지를로드해야하는 경우 항상 .gif 파일의 이미지 태그에 gif를 포함 할 수 있습니다 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)
    }
} 

as subview 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 :

위에서 제안했듯이 FLAnimatedImageView와 함께 FLAnimatedImage를 사용하고 있습니다. 그리고 xcassets에서 데이터 세트로 gif를로드하고 있습니다. 이를 통해 iPhone 및 iPad 용으로 모양 및 앱 슬라이스 목적으로 다른 gif를 제공 할 수 있습니다. 이것은 내가 시도한 다른 것보다 훨씬 더 성능이 좋습니다. .stopAnimating ()을 사용하여 일시 중지하는 것도 쉽습니다.

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

0

스위프트킹 피셔

   lazy var animatedPart: AnimatedImageView = {
        let img = AnimatedImageView()
        if let src = Bundle.main.url(forResource: "xx", withExtension: "gif"){
            img.kf.setImage(with: src)
        }
        return img
   }()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.