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

Sky*_*ren 10 core-graphics gif swift ios11

我最近在创建一个Gif时遇到了一个问题,如果它的颜色太大就会丢失.但是感谢SO的帮助,有人能够帮我找到一个工作并创建我自己的颜色图.

以前的问题... 保存动画Gif时iOS颜色不正确

这在iOS 11中运行良好.我在文档中找不到任何改变的东西,并且会使它不再起作用.我发现如果我删除了kCGImagePropertyGIFImageColorMap一个Gif生成但它有原始问题,如果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: "")!
}
Run Code Online (Sandbox Code Playgroud)

这是下载测试项目的链接.请注意,如果您在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
    }
}
Run Code Online (Sandbox Code Playgroud)

色彩表

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))
    }
}
Run Code Online (Sandbox Code Playgroud)

Sky*_*ren 1

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