Подтвердить что ты не робот

Создание графических карт Gif Image в iOS 11

Недавно у меня возникла проблема при создании Gif, где, если он получил слишком большие цвета, пропал. Однако благодаря помощи от SO кто-то смог помочь мне найти работу и создать свою собственную цветную карту.

Предыдущий вопрос здесь... Цвета iOS неправильны при сохранении анимированного Gif

Это отлично работало до 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: "")!
}

Вот ссылка для загрузки тестового проекта. Обратите внимание, что если вы запустите его на 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
    }
}

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

Ответ 1

Это ошибка в iOS 11.0 и 11.1. Apple исправила это в iOS 11.2+

Ответ 2

Я видел проект zip. это кажется не "осторожным"..:)

В любом случае:

  • Ниже вы можете найти минимальный код, который работает для iOS 11.
  • мы можем начать с этого

  • вопросы:

    1) что должно произойти для разных размеров? мы муза изменим размер GIF, сделаем черную область вокруг оригинального изображения в новом большом изображении

    2) можете ли вы дать мне более подробную информацию о цветовых картах?

    3) Что это за материал с матрицами? кажется, вы хотите заполнить черный? это не разумный и быстрый подход. Я буду использовать функции Apple для увеличения/заполнения фона.

Я могу помочь вам, как только вы любезно ответили.

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

}

}