Skip to content

Instantly share code, notes, and snippets.

@amomchilov
Last active June 28, 2023 19:52
Show Gist options
  • Save amomchilov/5dbb15f5331ac183e19d34d15fb835ff to your computer and use it in GitHub Desktop.
Save amomchilov/5dbb15f5331ac183e19d34d15fb835ff to your computer and use it in GitHub Desktop.
Vertically stitches frames of a GIF into a single image
let image = #imageLiteral(resourceName: "Arrow.gif")
let imageRep = image.representations.first! as! NSBitmapImageRep
let numFrames = imageRep.value(forProperty: NSImageFrameCount) as! Int
let numLoops = imageRep.value(forProperty: NSImageCurrentFrameDuration) as! Float
var cgImages = [CGImage]()
var nsImages = [NSImage]()
var size = NSSize()
for frame in 0..<numFrames {
let nsNumber = NSNumber(value: frame)
imageRep.setProperty(NSImageCurrentFrame, withValue: nsNumber)
print(imageRep.value(forProperty: NSImageCurrentFrame) as Any)
let cgImage = imageRep.cgImage!
cgImages.append(cgImage)
nsImages.append(NSImage(cgImage: cgImage, size: imageRep.size))
size = imageRep.size
}
cgImages
nsImages
let typicalImage = nsImages.first!
let typicalImageRep = typicalImage.representations.first!
let typicalCGImage = cgImages.first!
let typicalHeight = Int(typicalImageRep.size.height)
let totalHeight = typicalHeight * nsImages.count
let typicalWidth = Int(typicalImageRep.size.width)
let bitsPerComponent = typicalImageRep.bitsPerSample
let colorSpace = typicalCGImage.colorSpace!
CGImageAlphaInfo.noneSkipLast
let bitmapInfo = typicalCGImage.bitmapInfo.rawValue | typicalCGImage.alphaInfo.rawValue
let ctx = CGContext(data: nil, width: typicalWidth, height: totalHeight,
bitsPerComponent: bitsPerComponent, bytesPerRow: 0,
space: colorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)!
//let ctx = CGContext(data: nil, width: width, height: totalHeight,
// bitsPerComponent: bitsPerComponent, bytesPerRow: 0,
// space: colorSpace, bitmapInfo: bitmapInfo)!
var steps = [NSImage]()
for (index, image) in cgImages.enumerated() {
let y = totalHeight - typicalHeight - index * typicalHeight
ctx.draw(image, in: CGRect.init(x: 0, y: y, width: typicalWidth, height: typicalHeight))
let cgImage = ctx.makeImage()!
let i = NSImage(cgImage: cgImage, size: NSSize(width: cgImage.width, height: cgImage.height))
steps.append(i)
}
steps
let cgImage = ctx.makeImage()!
NSImage(cgImage: cgImage, size: NSSize(width: cgImage.width, height: cgImage.height))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment