在iOS 11中创建GIF图像颜色映射

10

最近我在制作Gif时遇到了一个问题,如果文件太大,颜色会消失。但是幸运的是,在Stack Overflow上得到帮助后,有人帮助我找到了解决方法并创建了自己的颜色映射。

之前的问题在这里...iOS Colors Incorrect When Saving Animated Gif

这个方法一直很好用,直到iOS 11出现了问题。我在文档中没有找到任何更改,也不知道为什么不能再用了。我发现,如果我删除kCGImagePropertyGIFImageColorMap,虽然生成了一个gif文件,但它仍然存在颜色丢失的问题,就像我的之前的问题一样。这很容易理解,因为添加这个属性就是为了解决这个问题。

疑似问题......

func createGifFromImage(_ image: UIImage) -> URL{

    let fileProperties: [CFString: CFDictionary] = [kCGImagePropertyGIFDictionary: [
        kCGImagePropertyGIFHasGlobalColorMap: false as NSNumber] as CFDictionary]

    let documentsDirectoryPath = "file://\(NSTemporaryDirectory())"

    if let documentsDirectoryURL = URL(string: documentsDirectoryPath){

        let fileURL = documentsDirectoryURL.appendingPathComponent("test.gif")
        let destination = CGImageDestinationCreateWithURL(fileURL as CFURL, kUTTypeGIF, 1, nil)!

        CGImageDestinationSetProperties(destination, fileProperties as CFDictionary);

        let colorMap = image.getColorMap()
        print("ColorMap \(colorMap.exported as NSData)")

        let frameProperties: [String: AnyObject] = [
            String(kCGImagePropertyGIFImageColorMap): colorMap.exported as NSData
        ]

        let properties: [String: AnyObject] = [
            String(kCGImagePropertyGIFDictionary): frameProperties as AnyObject
        ]

        CGImageDestinationAddImage(destination, image.cgImage!, properties as CFDictionary);

        if (!CGImageDestinationFinalize(destination)) {
            print("failed to finalize image destination")
        }

        return fileURL
    }

    //shouldn't get here
    return URL(string: "")!
}

这里有一个下载测试项目的链接。请注意,如果您在10.3模拟器上运行它,它会很好地工作,但如果您在iOS 11上运行它,则是一个白色图像。 https://www.dropbox.com/s/hdmkwyz47ondd52/gifTest2.zip?dl=0 其他被引用的代码...
extension UIImage{
    //MARK: - Pixel
    func getColorMap() -> ColorMap {

        var colorMap = ColorMap()

        let pixelData = self.cgImage!.dataProvider!.data
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        var byteIndex = 0

        for _ in 0 ..< Int(size.height){
            for _ in 0 ..< Int(size.width){

                let color = Color(red: data[byteIndex], green: data[byteIndex + 1], blue: data[byteIndex + 2])
                colorMap.colors.insert(color)
                byteIndex += 4
            }
        }

        return colorMap
    }
}

色彩映射
struct Color : Hashable {
    let red: UInt8
    let green: UInt8
    let blue: UInt8

    var hashValue: Int {
        return Int(red) + Int(green) + Int(blue)
    }

    public static func == (lhs: Color, rhs: Color) -> Bool {
        return [lhs.red, lhs.green, lhs.blue] == [rhs.red, rhs.green, rhs.blue]
    }
}


struct ColorMap {
    var colors = Set<Color>()

    var exported: Data {
        let data = Array(colors)
            .map { [$0.red, $0.green, $0.blue] }
            .joined()

        return Data(bytes: Array(data))
    }
}
2个回答

1

这是iOS 11.0和11.1中的一个错误。苹果已在iOS 11.2+中修复了此错误。


-6

我看到了zip项目,似乎不是很"Swifty"。 :)

无论如何:

  • 下面是适用于iOS 11的最小代码。
  • 我们可以从这里开始

  • 问题:

    1)不同尺寸应该发生什么?我们必须调整GIF或在新的大图像中围绕原始图像制作黑色区域

    2)您能否给我更多关于颜色映射的细节?

    3)矩阵的所有内容是什么?它似乎想要填充黑色?这不是聪明和更快的方法。我将使用苹果函数来缩放/填充背景。

一旦您友好地回答了我的问题,我可以帮助您。

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    if let image = UIImage(named: "image1"){
        createGIFFrom(image: image)
    }
}

final func localPath()->URL{
    let tempPath = NSTemporaryDirectory()
    let url = URL.init(fileURLWithPath: tempPath)
    return url.appendingPathComponent("test.gif")
}


private final func createGIFFrom(image: UIImage){
    let fileURL = self.localPath()
    let type: CFString = kUTTypeGIF// kUTTypePNG
    // from apple code:
    //https://developer.apple.com/library/content/technotes/tn2313/_index.html

    guard let myImageDest = CGImageDestinationCreateWithURL(fileURL as CFURL, type, 1, nil) else{
        return
    }

    guard let imageRef = image.cgImage else{
        return
    }

    // Add an image to the image destination
    CGImageDestinationAddImage(myImageDest, imageRef, nil)
    CGImageDestinationFinalize(myImageDest)

    print("open image at: \(fileURL)")

}

}


2
很遗憾,这并没有什么帮助。问题在于当创建更大的gif时,颜色会丢失,正如我在原始的SO问题中所链接的那样。添加颜色映射可以解决此问题,但它不再适用于iOS 11。这个答案并没有解决任何问题。我正在寻找一个解决iOS 11中颜色丢失问题的答案。 - Skyler Lauren
现在代码变得更加简洁了。很抱歉我没有看原帖。 所以主要目标是放大gif图像,对吗?(例如示例中的4个按钮...) - ingconti
样本将它们放大而不是缩放。问题在于保存较大的 GIF 时会丢失颜色。 - Skyler Lauren

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