将GIF图像转换为NSData

12

我在我的相册中有一张gif图像。当我使用UIImagePickerController选择那张图片时,我需要将其转换为NSData以进行存储。

之前,我使用了

NSData *thumbData = UIImageJPEGRepresentation(thumbnail, 0.5);

但是它不能用于gif图像。thumbData将为nil。

  1. 我如何从gif图像获取NSData

  2. 我如何知道这是需要特殊处理的gif图像?


你也使用了UIImagePNGRepresentation(thumbnail)吗? - Areal-17
请查看此链接。它可能对您有所帮助。 - George
你解决了问题吗? - Varun Naharia
5个回答

11

关键在于将GIF文件或URL直接下载转换为NSData,而不是将其作为UIImage。绕过UIImage将使GIF文件保持动画。

这是一些将GIF文件转换为NSData的代码:

NSString *filePath = [[NSBundle mainBundle] pathForResource: @"gifFileName" ofType: @"gif"];

NSData *gifData = [NSData dataWithContentsOfFile: filePath];

但说实话,你应该真的考虑不再使用GIF。


4

Swift

动态图不能放在资源文件中。

let path = Bundle.main.path(forResource: "loader", ofType: "gif")!
let data = try! Data(contentsOf: URL(fileURLWithPath: path))
return data

2

1
如果你正在寻找一个快速的答案,这里有一个UIImage的扩展可以完成这项工作。
import UIKit
import MobileCoreServices

extension UIImage {
    func UIImageAnimatedGIFRepresentation(gifDuration: TimeInterval = 0.0, loopCount: Int = 0) throws -> Data {
        let images = self.images ?? [self]
        let frameCount = images.count
        let frameDuration: TimeInterval = gifDuration <= 0.0 ? self.duration / Double(frameCount) : gifDuration / Double(frameCount)
        let frameDelayCentiseconds = Int(lrint(frameDuration * 100))
        let frameProperties = [
            kCGImagePropertyGIFDictionary: [
                kCGImagePropertyGIFDelayTime: NSNumber(value: frameDelayCentiseconds)
            ]
        ]

        guard let mutableData = CFDataCreateMutable(nil, 0),
           let destination = CGImageDestinationCreateWithData(mutableData, kUTTypeGIF, frameCount, nil) else {
            throw NSError(domain: "AnimatedGIFSerializationErrorDomain",
                          code: -1,
                          userInfo: [NSLocalizedDescriptionKey: "Could not create destination with data."])
        }
        let imageProperties = [
            kCGImagePropertyGIFDictionary: [kCGImagePropertyGIFLoopCount: NSNumber(value: loopCount)]
        ] as CFDictionary
        CGImageDestinationSetProperties(destination, imageProperties)
        for image in images {
            if let cgimage = image.cgImage {
                CGImageDestinationAddImage(destination, cgimage, frameProperties as CFDictionary)
            }
        }

        let success = CGImageDestinationFinalize(destination)
        if !success {
            throw NSError(domain: "AnimatedGIFSerializationErrorDomain",
                          code: -2,
                          userInfo: [NSLocalizedDescriptionKey: "Could not finalize image destination"])
        }
        return mutableData as Data
    }
}
  1. 虽然上述扩展可以完成工作,但从图像选择器处理gif更简单,这是在UIImagePickerControllerDelegate函数中的实现。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let info = Dictionary(uniqueKeysWithValues: info.map {key, value in (key.rawValue, value)})
    if let url = info[UIImagePickerController.InfoKey.referenceURL.rawValue] as? URL, url.pathExtension.lowercased() == "gif" {
       picker.dismiss(animated: false, completion: nil)
       url.getGifImageDataFromAssetUrl(completion: { imageData in
           // Use imageData here.
       })
       return
    }
}

使用URL中的扩展函数。
import UIKit
import Photos

extension URL {
    func getGifImageDataFromAssetUrl(completion: @escaping(_ imageData: Data?) -> Void) {
        let asset = PHAsset.fetchAssets(withALAssetURLs: [self], options: nil)
        if let image = asset.firstObject {
            PHImageManager.default().requestImageData(for: image, options: nil) { (imageData, _, _, _) in
                completion(imageData)
            }
        }
    }
}

动态图太慢了,我尝试了不同的组合但都没有效果。 - IDev
你确定“Data -> UIImage”的转换没有夹紧延迟时间吗?根据一些资料,任何持续时间小于0.05的帧将夹紧为0.1。 - MMujtabaRoohani
我该如何确保呢?你能指导一下吗?我尝试调整了“frameDelayCentiseconds”变量,但是结果几乎没有改变。 - IDev
非常感谢!这帮助我更新Gif数据,然后再次转换为Gif数据。 - guozqzzu

1

将.GIF文件转换为NSData的代码 -

NSString *pathForFile = [[NSBundle mainBundle] pathForResource: @"myGif" ofType: @"gif"];

NSData *dataOfGif = [NSData dataWithContentsOfFile: pathForFile];

NSLog(@"Data: %@", dataOfGif);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接