# frozen_string_literal: true #!/usr/bin/env ruby require 'optparse' headless = true actions = [] images = [] original_image = nil opts = OptionParser.new do |o| o.banner = 'Usage: image_voodoo [actions] image_file' o.separator 'Perform actions/transformations on an image.' o.separator '' o.separator 'Examples:' o.separator ' image_voodoo --dim small.jpg # Print the dimensions' o.separator '' o.separator ' # Make a thumbnail, preview it, and then save it.' o.separator ' image_voodoo --thumbnail 50 --preview --save thumb.png large.jpg' o.separator '' o.separator ' # Make 2 thumbnails, showing dimensions and previewing them' o.separator ' image_voodoo --dim --resize 50x50 --dim --preview --save t1.jpg' o.separator ' --pop --resize 40x40 --dim --preview --save t2.jpg image.jpg' o.separator '' o.separator 'Actions:' o.on('-a', '--alpha rrggbb', 'Make color transparent in image') do |c| o.usage 'rrggbb is in hexidecimal format' if c !~ /[[:xdigit:]]{6,6}/ actions << ->(img) { img.alpha(c) } end o.on('-b', '--brightness SCALE,OFFSET', 'Adjust brightness') do |args| scale, offset = args.split(/,/).map(&:to_f) o.usage 'You need to specify proper scale and offset' unless scale && offset actions << ->(img) { img.adjust_brightness(scale, offset) } end o.on('-B', '--border WIDTH,COLOR,STYLE', 'Add a simple border') do |args| width, color, style = args.split(/,/) options = { width: width, color: color, style: style } actions << ->(img) { img.add_border(options) } end o.on('-d', '--dimensions', 'Print the image dimensions') do actions << ->(img) { img.tap { puts "#{img.width}x#{img.height}" } } end o.on('-g', '--greyscale', 'Convert image to greyscale') do actions << ->(img) { img.greyscale } end o.on('-h', '--flip_horizontally') do actions << ->(img) { img.flip_horizontally } end o.on('-m', '--metadata') do actions << ->(img) { img.tap { puts img.metadata } } end o.on('-n', '--negative', 'Make a negative out of the image') do actions << ->(img) { img.negative } end o.on('-o', '--orient', 'Rotate image to orient it based on metadata') do actions << ->(img) { img.correct_orientation } end o.on('-q', '--quality 0..1', Float, 'Set % of quality for lossy compression') do |quality| actions << ->(img) { img.quality(quality) } end o.on('-R', '--rotate 0..360', Float, 'Set angle to rotate image') do |angle| actions << ->(img) { img.rotate(angle.to_f) } end o.on('-r', '--resize WIDTHxHEIGHT', 'Make a new resized image') do |dim| width, height = dim.split(/x/i).map(&:to_i) o.usage 'You need to specify proper dimensions' unless width && width > 0 && height && height > 0 actions << ->(img) { img.resize(width, height) } end o.on('-s', '--save FILENAME', 'Save the results to a new file') do |f| actions << ->(img) { img.tap { img.save(f) } } end o.on('-t', '--thumbnail SIZE', Integer, 'Create a thumbnail of the given size') do |size| actions << ->(img) { img.thumbnail(size) } end o.on('-v', '--flip_vertically') { actions << ->(img) { img.flip_vertically } } o.on('-p', '--preview', 'Preview the image. Close the frame window', 'to continue, or quit the application to', 'abort the action pipeline') do headless = false actions << lambda do |img| done = false img.preview { done = true } Thread.pass until done img end end o.on('--push', 'Save the current image to be popped later') do actions << ->(img) { img.tap { images << img } } end o.on('--pop', 'Revert back to the previous image') do actions << -> { images.pop || original_image } end o.on('-f', '--format', 'Print the image format') do actions << ->(img) { img.tap { img.format } } end o.on_tail('-h', '--help', 'Show this message') { o.usage } def o.usage(msg=nil) puts msg if msg puts self exit 1 end end opts.parse!(ARGV) opts.usage('You need to supply a source image filename.') unless ARGV.first opts.usage('You need to supply one or more actions.') if actions.empty? # For this binstub we only want to load non-headless if we are using # the preview feature. top of See lib/image_voodoo.rb for more info... require 'image_voodoo/needs_head' unless headless require 'image_voodoo' file_name = ARGV.first method = file_name =~ /^http:/ ? :from_url : :with_image ImageVoodoo.send(method, file_name) do |img| original_image = img actions.each { |act| img = act.call(img) } end # Be sure we exit out of swing java.lang.System.exit(0)