Skip to content

Instantly share code, notes, and snippets.

@mbuchetics
Last active October 26, 2021 06:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbuchetics/af26fc6d788a304dee98962efc22de11 to your computer and use it in GitHub Desktop.
Save mbuchetics/af26fc6d788a304dee98962efc22de11 to your computer and use it in GitHub Desktop.
//
// GifExporter.swift
// Flipbook
//
// Created by Matthias Buchetics on 02.12.20.
// Copyright © 2020 Tinkado. All rights reserved.
//
import Foundation
import UIKit
import ImageIO
import MobileCoreServices
struct GifExporterSettings {
var size: CGSize
var fps: Int
var loop: Bool
var filename: String
var filenameExt = "gif"
init(size: CGSize, fps: Int, loop: Bool, fileName: String = "flipbook") {
self.size = size
self.fps = fps
self.loop = loop
self.filename = fileName
}
var outputURL: URL {
cacheURL(filename: filename, ext: filenameExt)
}
}
class GifExporter: Exporter {
let settings: GifExporterSettings
init(settings: GifExporterSettings) {
self.settings = settings
}
func export(frames: [LazyFrame], completion: @escaping (Result<URL, ExportError>) -> Void) {
try? FileManager.default.removeItem(atPath: settings.outputURL.path)
let fileProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [
kCGImagePropertyGIFLoopCount as String: settings.loop ? 0 : 1
]] as CFDictionary
let frameProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [
kCGImagePropertyGIFDelayTime as String: 1.0 / Double(settings.fps)
]] as CFDictionary
guard
let url = settings.outputURL as CFURL?,
let destination = CGImageDestinationCreateWithURL(url, kUTTypeGIF, frames.count, nil)
else {
return
}
CGImageDestinationSetProperties(destination, fileProperties)
for frame in frames {
autoreleasepool {
if let cgImage = frame.computeImage(settings.size).cgImage {
CGImageDestinationAddImage(destination, cgImage, frameProperties)
}
}
}
if CGImageDestinationFinalize(destination) {
completion(.success(self.settings.outputURL))
} else {
completion(.failure(.undefined))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment