Skip to content

Instantly share code, notes, and snippets.

@sudara
Created June 21, 2021 17:01
Show Gist options
  • Save sudara/10679483a05431c6ecd79eabf45738f9 to your computer and use it in GitHub Desktop.
Save sudara/10679483a05431c6ecd79eabf45738f9 to your computer and use it in GitHub Desktop.
Recover your .skitch files
#!/usr/bin/env ruby
# Prereq:
# gem install ox
# Usage:
# cd my_skitch_directory
# ./sktich2image.rb
# Warning #1: This doesn't check for the target .png/.jpg, etc, it just writes to the same filename as the skitch but with a png/jpg extension.
# Warning #2: None of the skitch annotations will end up in the image. Sorry! If you find a way to automate the newer skitch app to process a directory of images, let me know
# I wanted to use nokogiri, but libxml has an attribute value max length
# which caused issues since our images are embedded in an attribute
# => [#<Nokogiri::XML::SyntaxError: 5:10000134: FATAL: AttValue length too long>, #<Nokogiri::XML::SyntaxError: 5:10000134: FATAL: Memory allocation failed>, #<Nokogiri::XML::SyntaxError: 5:10000134: FATAL: attributes construct error>, #<Nokogiri::XML::SyntaxError: 5:10000134: FATAL: Couldn't find end of Start Tag image line 5>]
require 'ox'
require "base64"
Dir["*.skitch"].each do |skitch_filename|
File.open(skitch_filename) do |skitch_file|
puts "processing #{skitch_filename}..."
doc = Ox.parse(IO.read(skitch_file))
attribute = doc.locate('svg/image/@xlink:href').first
prefix, data = attribute.split(',', 2)
# prefix looks like "data:image/png;base64"
extension = prefix.partition('/').last.split(';').first
file_to_write = skitch_file.to_path.gsub('.skitch', "." + extension)
puts "writing #{file_to_write}"
File.open(file_to_write, "wb") do |f|
f.write(Base64.decode64(data))
end
File.utime(File.atime(skitch_filename), File.mtime(skitch_filename), file_to_write)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment