Skip to content

Instantly share code, notes, and snippets.

@sonota88
Last active December 26, 2025 22:56
Show Gist options
  • Select an option

  • Save sonota88/817b22416e6efa27f018d6d9cf2b8594 to your computer and use it in GitHub Desktop.

Select an option

Save sonota88/817b22416e6efa27f018d6d9cf2b8594 to your computer and use it in GitHub Desktop.
RubyでPNGにLibreOffice Drawのodgファイルを埋め込んで再編集可能にする
require "base64"
require "json"
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "chunky_png", "1.4.0"
end
KEYWORD_EMBEDDED_SOURCE = "Embedded Source"
EmbeddedSourceContent = Struct.new(:type, :filename, :file)
def cmd_embed(f_png, f_odg)
odg_data = File.binread(f_odg)
odg_b64str = Base64.encode64(odg_data)
esc = EmbeddedSourceContent.new(
".odg",
File.basename(f_odg),
odg_b64str
)
f_out = f_png.delete_suffix(".png") + ".odg.png"
image = ChunkyPNG::Image.from_file(f_png)
image.metadata[KEYWORD_EMBEDDED_SOURCE] = JSON.generate(esc.to_h)
image.save(f_out)
end
def cmd_extract(f_png, f_odg = nil)
image = ChunkyPNG::Image.from_file(f_png)
json = image.metadata[KEYWORD_EMBEDDED_SOURCE]
esc = EmbeddedSourceContent.new(**JSON.parse(json))
odg_data = Base64.decode64(esc.file)
f_out = f_odg || esc.filename
File.binwrite(f_out, odg_data)
end
def print_help
this_cmd = $0
puts <<~HELP
USAGE:
ruby #{this_cmd} embed {f_png} {f_odg}
ruby #{this_cmd} extract {f_png} [f_odg_output]
HELP
end
def main(args)
case args[0]
when "em", "embed"
args.shift
f_png = args.shift
f_odg = args.shift
cmd_embed(f_png, f_odg)
when "ex", "extract"
args.shift
f_png = args.shift
f_odg = args.shift
cmd_extract(f_png, f_odg)
when "-h", "--help"
print_help
else
print "invalid arguments\n\n"
print_help
exit 1
end
end
main(ARGV)
@sonota88
Copy link
Author

RubyでPNGにLibreOffice Drawのodgファイルを埋め込んで再編集可能にする
https://qiita.com/sonota88/items/8d64cd21ce2fc14bf5ed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment