Creating Gif Image Color Maps in iOS 11

匿名 (未验证) 提交于 2019-12-03 03:05:02

问题:

I recently was having an issue when creating a Gif where if it got too big colors went missing. However thanks to help from SO someone was able to help me find a work around and create my own color map.

Previous Question here...iOS Colors Incorrect When Saving Animated Gif

This worked great up until iOS 11. I can't find anything in the docs that changed and would make this no longer work. What I have found is if I remove kCGImagePropertyGIFImageColorMap A gif is generated but it has the original issue where colors go missing if the gif gets to large like my previous question. This makes sense as this was added to fix that issue.

Suspected Issue...

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: "")! }

Here is a link to download a test project. Note if you run it on a 10.3 simulator it works great but if you run it on iOS 11 it is a white image.

https://www.dropbox.com/s/hdmkwyz47ondd52/gifTest2.zip?dl=0

Other code that is referenced...

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

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

回答1:

This is a bug in iOS 11.0 and 11.1. Apple has fixed this in iOS 11.2+



回答2:

I saw zip project. it's seems not "swifty".. :)

Anyway:

  • below You can find minimal code that works for iOS 11.
  • we can start from this

  • questions:

    1) what should happen for different sizes? we muse resize GIF of make a black area around original image in a new big image

    2) can you give me more details about color maps?

    3) what is all the stuff with matrixes? it seems you want to fill in black? this is not the smart and quicker approach. I will use Apple functions to scale up/fill background.

I can help You once You have kindly answered.

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

}



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!