module Magick::Screwdrivers
Constants
- VERSION
Public Class Methods
collage(files, options={})
click to toggle source
# File lib/rmagick/screwdrivers/collage.rb, line 7 def self.collage files, options={} options = { :columns => 5, :scale_range => 0.1, :thumb_width => 120, :rotate_angle => 20, :background => 'white', :border => '#DDDDDD', :logger => nil }.merge(options) files = "#{files}/*" if File.directory?(files) imgs = ImageList.new imgnull = Image.new(options[:thumb_width],options[:thumb_width]) { self.background_color = 'transparent' } (options[:columns]+2).times { imgs << imgnull.dup } Dir.glob("#{files}") { |f| begin i = img_from_file(f) rescue warn(options[:logger], "Skipping invalid file #{f}…") next end scale = (1.0 + options[:scale_range]*Random::rand(-1.0..1.0))*options[:thumb_width]/[i.columns, i.rows].max imgs << imgnull.dup if (imgs.size % (options[:columns]+2)).zero? imgs << i.auto_orient.thumbnail(scale).polaroid( Random::rand(-options[:rotate_angle]..options[:rotate_angle]) ) imgs << imgnull.dup if (imgs.size % (options[:columns]+2)) == options[:columns]+1 } (2*options[:columns]+4-(imgs.size % (options[:columns]+2))).times { imgs << imgnull.dup } info options[:logger], "Montaging image [#{options[:columns]}×#{imgs.size/(options[:columns]+2)-2}]" imgs.montage { self.tile = Magick::Geometry.new(options[:columns]+2) self.geometry = "-#{options[:thumb_width]/5}-#{options[:thumb_width]/4}" self.background_color = options[:background] }.trim(true).border(10,10,options[:background]).border(1,1,options[:border]) end
debug(logger = nil, msg = nil)
click to toggle source
# File lib/rmagick/screwdrivers/helpers.rb, line 37 def self.debug logger = nil, msg = nil logger.debug(msg) if logger && logger.respond_to?(:debug) end
img_from_file(file)
click to toggle source
¶ ↑
Image preparation =================================¶ ↑
¶ ↑
# File lib/rmagick/screwdrivers/helpers.rb, line 12 def self.img_from_file file img = Magick::Image::read(file).first # case img.orientation # when Magick::RightTopOrientation # img.rotate!(90) # when Magick::BottomRightOrientation # img.rotate!(180) # when Magick::LeftBottomOrientation # img.rotate!(-90) # end img end
info(logger = nil, msg = nil)
click to toggle source
# File lib/rmagick/screwdrivers/helpers.rb, line 34 def self.info logger = nil, msg = nil logger.info(msg) if logger && logger.respond_to?(:info) end
poster(file, text1, text2, options={})
click to toggle source
# File lib/rmagick/screwdrivers/poster.rb, line 7 def self.poster file, text1, text2, options={} options = { :color => '#FFFFFF', :stroke => nil, :width => 600, :type => :classic, # :classic for black square around :lineheight => 6, :background => '#000000', :font => '/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf', :max_font_size => 48, :logger => nil }.merge(options) text1 ||= '' text2 ||= '' options[:lineheight] = 3 if options[:lineheight] < 3 img = img_from_file(file) img.thumbnail!(options[:width].to_f/img.columns.to_f) mark = Magick::Image.new(img.columns, img.rows) do self.background_color = options[:type] == :classic ? options[:background] : 'transparent' end gc = Magick::Draw.new pointsize = [img.columns, options[:max_font_size]].min classic_margin = 0 loop do gc.pointsize = pointsize -= 1 + pointsize / 33 m1 = gc.get_type_metrics(text1) w1 = m1.width h1 = (m1.bounds.y2 - m1.bounds.y1).round m2 = gc.get_type_metrics(text2) w2 = m2.width h2 = (m2.bounds.y2 - m2.bounds.y1).round if w1 < img.columns - 10*options[:lineheight] && w2 < img.columns - 10*options[:lineheight] if options[:type] == :classic classic_margin = h2 mark.resize! img.columns+options[:lineheight]*14/3, img.rows+options[:lineheight]*8+h1+h2 gc.stroke_width = options[:lineheight]/3 gc.stroke = '#FFFFFF' gc.fill = options[:background] gc.rectangle(options[:lineheight]*7/6, options[:lineheight]*7/6, \ img.columns+options[:lineheight]*21/6, img.rows+options[:lineheight]*21/6) gc.composite( 7*options[:lineheight]/3, 7*options[:lineheight]/3, 0, 0, img, Magick::OverCompositeOp ) gc.draw mark end break end end gc.fill = options[:color] gc.stroke = options[:stroke] || 'none' gc.stroke_width = 1 gc.font = options[:font] case options[:type] when :classic gc.annotate(mark, 0, 0, 0, classic_margin+2*options[:lineheight], text1) do self.gravity = Magick::SouthGravity end else gc.annotate(mark, 0, 0, 0, 0, text1) do self.gravity = Magick::NorthGravity end end gc.annotate(mark, 0, 0, 0, 0, text2) do self.gravity = Magick::SouthGravity end case options[:type] when :classic mark when :negative img.composite(mark, Magick::SouthEastGravity, Magick::SubtractCompositeOp) when :standard img.composite(mark, Magick::SouthEastGravity, Magick::OverCompositeOp) else warn options[:logger], "Invalid type: #{options[:type]}" end end
scale(file, options={})
click to toggle source
# File lib/rmagick/screwdrivers/scale.rb, line 8 def self.scale file, options={} options = { :widths => 600, :date_in_watermark => false, :watermark => nil, :logger => nil }.merge(options) img = img_from_file file date = img.get_exif_by_number(36867)[36867] date = Date.parse(date.gsub(/:/, '/')) if date date ||= Date.parse(img.properties['exif:DateTime'].gsub(/:/, '/')) if img.properties['exif:DateTime'] date ||= Date.parse(img.properties['date:modify']) if img.properties['date:modify'] date ||= Date.parse(img.properties['date:create']) if img.properties['date:create'] date ||= Date.parse(img.properties['xap:CreateDate']) if img.properties['xap:CreateDate'] options[:watermark] = ([ options[:watermark], date.strftime('%y/%m/%d')] - [nil] ).join(' :: ').strip if options[:date_in_watermark] result = ImageList.new [*options[:widths]].each { |sz| unless Integer === sz && sz < img.columns && sz > 0 warn options[:logger], "Invalid width #{sz} (original is #{img.columns}), skipping…" next end curr = img.resize_to_fit(sz) if will_wm = (options[:watermark] && curr.rows >= 400) mark = Magick::Image.new(curr.rows, curr.columns) do self.background_color = 'transparent' end draw = Magick::Draw.new draw.encoding = 'Unicode' draw.annotate(mark, 0, 0, 5, 2, options[:watermark]) do self.encoding = 'Unicode' self.gravity = Magick::SouthEastGravity self.fill 'rgba(60%, 60%, 60%, 0.40)' self.stroke = 'none' self.pointsize = 1 + 2 * Math.log(sz, 3).to_i self.font_family = 'Comfortaa' self.font_weight = Magick::NormalWeight self.font_style = Magick::NormalStyle end curr = curr.composite(mark.rotate(-90), Magick::SouthEastGravity, Magick::SubtractCompositeOp) end info options[:logger], "Scaling to width #{curr.rows}×#{curr.columns}, watermark: “#{will_wm ? options[:watermark] : 'NONE'}”" result << curr } result end