Skip to content

Instantly share code, notes, and snippets.

@vizv
Last active December 21, 2020 08:10
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 vizv/d6eb1559a72520edbd6f8e088c4f8199 to your computer and use it in GitHub Desktop.
Save vizv/d6eb1559a72520edbd6f8e088c4f8199 to your computer and use it in GitHub Desktop.
comics-cutter
setting:
source:
dir: src
format: jpg
output:
dir: _output
format: jpg
height: 1920
width: 1350
digits: 3
default:
margin:
top: 0
bottom: 0
left: 0
right: 0
files:
02.jpg:
margin:
top: 3180
override:
3:
height: 1320
#!/usr/bin/env ruby
require 'fileutils'
require 'yaml'
DRYRUN = ENV['DRYRUN']
config = YAML.load(File.read('config.yml'))
source_dir = config['setting']['source']['dir']
output_dir = config['setting']['output']['dir']
source_fmt = config['setting']['source']['format']
output_fmt = config['setting']['output']['format']
img_width = config['setting']['width']
img_height = config['setting']['height']
digits = config['setting']['digits']
default_top = config['default']['margin']['top']
default_bottom = config['default']['margin']['bottom']
default_left = config['default']['margin']['left']
default_right = config['default']['margin']['right']
default_height = config['default']['height'] || img_height
default_width = config['default']['width'] || img_width
FileUtils.rm_rf output_dir unless DRYRUN
FileUtils.mkdir_p output_dir unless DRYRUN
counter = 0
def die message
abort message unless DRYRUN
puts "[!] #{message}"
end
paths = Dir["#{source_dir}/*.#{source_fmt}"]
paths.each.with_index do |path, i|
file = File.basename(path)
puts "[+] processing #{file} [#{i+1}/#{paths.count}]..."
height, width = `identify -ping -format "%h:%w" #{path}`.split(':').map(&:to_i)
margin_top = config.dig('files', file, 'margin', 'top') || default_top
margin_bottom = config.dig('files', file, 'margin', 'bottom') || default_bottom
margin_left = config.dig('files', file, 'margin', 'left') || default_left
margin_right = config.dig('files', file, 'margin', 'right') || default_right
img_height = config.dig('files', file, 'height') || default_height
img_width = config.dig('files', file, 'width') || default_width
canvas_width = width - margin_left - margin_right
canvas_height = height - margin_top - margin_bottom
overrides = config.dig('files', file, 'override') || {}
override_height_sum = overrides.map do |_, override|
override.dig('height') || img_height
end.sum
remaining = (canvas_height - override_height_sum) % img_height
next die "error: wrong canvas width: #{canvas_width}" unless canvas_width == img_width
next die "error: wrong canvas height: #{remaining} px remaining" unless remaining == 0
offset = margin_top
count = (canvas_height - override_height_sum) / img_height + overrides.count
(1..count).each do |j|
counter += 1
output_file = "#{output_dir}/#{"%0#{digits}d" % counter}.#{output_fmt}"
puts " [+] generating #{output_file} [#{j}/#{count}]..."
source_height = config.dig('files', file, 'override', j, 'height') || default_height
source_width = source_height * default_width / default_height
command = <<~COMMAND
convert #{path}
-crop #{source_width}x#{source_height}+#{margin_left}+#{offset}
+repage
-resize #{img_width}x#{img_height}
#{output_file}
COMMAND
command = command.gsub(/\n /, ' ')
puts " [>] #{command}"
system command unless DRYRUN
offset += source_height
end
end
puts '[+] all done'
puts
puts 'press ENTER to exit'
gets
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment