Skip to content

Instantly share code, notes, and snippets.

@ptb
Created May 20, 2014 14:38
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 ptb/613b2c01b24e49c01040 to your computer and use it in GitHub Desktop.
Save ptb/613b2c01b24e49c01040 to your computer and use it in GitHub Desktop.
Command-line image resizer for Bootstrap grid
#!/usr/bin/env ruby
require 'pathname'
require 'optparse'
require 'ostruct'
require 'rmagick'
class RespImgs
CONTAINER_WIDTH = { xs: 320, sm: 750, md: 970, lg: 1170 }
NUM_COLUMNS = 12
GUTTER_WIDTH = 30
def self.calc(size, cols)
return (((size.to_f / NUM_COLUMNS) * cols) - GUTTER_WIDTH)
end
def self.parse(args)
options = OpenStruct.new
opt_parser = OptionParser.new do |opts|
opts.banner = 'Usage: respimg.rb [options]'
opts.separator ''
opts.on('-i FILE', 'Input file') do |file|
pn = Pathname.new(file)
options.path = pn.dirname.to_s
options.file = pn.basename(pn.extname.to_s).to_s
options.ext = pn.extname.to_s
end
opts.separator ''
opts.separator 'Number of columns this image will occupy:'
options.xs = CONTAINER_WIDTH[:xs] - GUTTER_WIDTH
opts.on('--xs COLUMNS', Integer,
'on extra small devices (< 768px)') do |cols|
options.xs = calc(CONTAINER_WIDTH[:xs], cols).to_i
end
opts.on('-s', '--sm COLUMNS', Integer,
'on small devices (≥ 768px)') do |cols|
options.sm = calc(CONTAINER_WIDTH[:sm], cols).to_i
end
opts.on('-m', '--md COLUMNS', Integer,
'on medium devices (≥ 992px)') do |cols|
options.md = calc(CONTAINER_WIDTH[:md], cols).to_i
end
opts.on('-l', '--lg COLUMNS', Integer,
'on large devices (≥ 1200px)') do |cols|
options.lg = calc(CONTAINER_WIDTH[:lg], cols).to_i
end
end
opt_parser.parse!(args)
return options
end
def self.resize(orig, out, x, q)
img = orig.resize_to_fit(x, 0)
img.write(out) { self.quality = q }
img.destroy!
end
def self.process(opts)
base = opts.path + '/' + opts.file
orig = Magick::Image::read(base + opts.ext).first
files = {}
if opts.sm && opts.sm <= orig.base_columns
files[:sm] = base + '-sm' + opts.ext
resize(orig, files[:sm], opts.sm, 85)
if (opts.sm * 2 <= orig.base_columns)
files[:sm2x] = base + '-sm@2x' + opts.ext
resize(orig, files[:sm2x], opts.sm * 2, 80)
end
end
if opts.md && opts.md <= orig.base_columns
files[:md] = base + '-md' + opts.ext
resize(orig, files[:md], opts.md, 85)
if (opts.md * 2 <= orig.base_columns)
files[:md2x] = base + '-md@2x' + opts.ext
resize(orig, files[:md2x], opts.md * 2, 80)
end
end
if opts.lg && opts.lg <= orig.base_columns
files[:lg] = base + '-lg' + opts.ext
resize(orig, files[:lg], opts.lg, 85)
if (opts.lg * 2 <= orig.base_columns)
files[:lg2x] = base + '-lg@2x' + opts.ext
resize(orig, files[:lg2x], opts.lg * 2, 80)
end
end
orig.destroy!
return files
end
def self.slim(files)
puts <<-DONE
picture
/[if IE 9]
<video style='display: none;'>
DONE
if files[:lg] && files[:lg2x]
puts <<-DONE
source(srcset='#{files[:lg]} 1x, #{files[:lg2x]} 2x' media='(min-width: 1200px)')/
DONE
elsif files[:lg]
puts <<-DONE
source(srcset='#{files[:lg]}' media='(min-width: 1200px)')/
DONE
end
if files[:md] && files[:md2x]
puts <<-DONE
source(srcset='#{files[:md]} 1x, #{files[:md2x]} 2x' media='(min-width: 992px)')/
DONE
elsif files[:md]
puts <<-DONE
source(srcset='#{files[:md]}' media='(min-width: 992px)')/
DONE
end
if files[:sm] && files[:sm2x]
puts <<-DONE
source(srcset='#{files[:sm]} 1x, #{files[:sm2x]} 2x')/
DONE
elsif files[:sm]
puts <<-DONE
source(srcset='#{files[:sm]}')/
DONE
end
puts <<-DONE
/[if IE 9]
</video>
DONE
if files[:sm] && files[:sm2x]
puts <<-DONE
img(srcset='#{files[:sm]} 1x, #{files[:sm2x]} 2x' alt='')/
DONE
elsif files[:sm]
puts <<-DONE
img(srcset='#{files[:sm]}' alt='')/
DONE
end
end
end
options = RespImgs.parse(ARGV)
files = RespImgs.process(options)
RespImgs.slim(files)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment