class FlickrCollage::Image
Class for Image
. Create collage and crop images @attr_reader [String] img_path
Path for saving images @attr_reader [Number] img_width
Width for images crop @attr_reader [Number] img_height
Height for images crop @attr_reader [String] collage_file
Collage file name @attr_reader [Boolean] clear_tmp
Delete all downloaded images
Constants
- IMG_HEIGHT
- IMG_WIDTH
Attributes
Public Class Methods
# File lib/FlickrCollage.rb, line 151 def initialize(opts = {}) opts[:img_path] ||= IMG_PATH opts[:img_width] ||= IMG_WIDTH opts[:img_height] ||= IMG_HEIGHT opts[:collage_file] ||= COLLAGE_FILE @img_path = opts[:img_path] @img_width = opts[:img_width] @img_height = opts[:img_height] @collage_file = opts[:collage_file] @clear_tmp = opts[:clear_tmp] end
Validates downloaded image
@param [String] file file path for downloaded image
@return [true] image is valid @return [false] image is not valid
# File lib/FlickrCollage.rb, line 170 def self.valid?(file) return false if file.nil? begin image = MiniMagick::Image.open(file) rescue StandardError => e warn "Image.valid: caught exception #{e}" raise e if RAISE_ERROR end image.valid? end
Public Instance Methods
Creates collage from 10 images
@param [Hash] opts @option opts [Array<String>] :files file paths for collage images
@return [true] collage created successfully @return [false] something went wrong
# File lib/FlickrCollage.rb, line 214 def collage(opts = {}) unless opts[:files].size == IMG_COUNT info "Not enough images for collage" return false end begin (1..4).each do |row| montage = MiniMagick::Tool::Montage.new files = montage_resize(files: opts[:files], row: row) files.each do |file| montage << file end montage << "-mode" montage << "Concatenate" montage << "-background" montage << "none" montage << "-geometry" montage << montage_geometry(row: row) montage << "-tile" montage << montage_tile(row: row) montage << montage_img_path(row: row) montage.call end rescue StandardError => e warn "Image.collage: caught exception #{e}" raise e if RAISE_ERROR end FileUtils.rm_rf("#{@img_path}tmp") if @clear_tmp true end
Creates simple collage 5x2 from 10 images
@param [Hash] opts @option opts [Array<String>] :files file paths for collage images
@return [true] collage created successfully @return [false] something went wrong @deprecated First collage implementation
# File lib/FlickrCollage.rb, line 285 def collage_simple(opts = {}) unless opts[:files].size == IMG_COUNT info "No images for collage" return false end begin montage = MiniMagick::Tool::Montage.new opts[:files].each do |file| montage << resize(file: file) end montage << "-mode" montage << "Concatenate" montage << "-background" montage << "none" montage << "-geometry" montage << "#{@img_width}x#{@img_height}+0+0" montage << "-tile" montage << "5x2" montage << "#{@img_path}#{@collage_file}.jpg" puts montage.inspect.to_s montage.call rescue StandardError => e warn "Image.collage: caught exception #{e}" raise e if RAISE_ERROR end true end
Resize image
@param [Hash] opts @option opts [String] :file file path for image @option opts [Number] :width (@img_width) image new width @option opts [Number] :height (@img_height) image new height
@return [String] file path for resized image
# File lib/FlickrCollage.rb, line 189 def resize(opts = {}) return false if opts[:file].nil? opts[:width] ||= @img_width opts[:height] ||= @img_height begin image = MiniMagick::Image.open(opts[:file]) resize_to_fill(opts[:width], opts[:height], image) file_resize = "#{@img_path}tmp/#{File.basename(opts[:file], ".jpg")}_resize.jpg" image.write file_resize debug "Resize #{opts[:file]} to #{opts[:width]}x#{opts[:height]}" rescue StandardError => e warn "Image.resize: caught exception #{e}" raise e if RAISE_ERROR end file_resize end
Smart image crop
@param [Number] width image new width @param [Number] height image new height @param [MiniMagick::Image] img image @param [String] gravity crop around
@return [MiniMagick::Image] cropped image
# File lib/FlickrCollage.rb, line 254 def resize_to_fill(width, height, img, gravity = "Center") cols, rows = img[:dimensions] img.combine_options do |cmd| if width != cols || height != rows scale_x = width / cols.to_f scale_y = height / rows.to_f if scale_x >= scale_y cols = (scale_x * (cols + 0.5)).round rows = (scale_x * (rows + 0.5)).round cmd.resize cols.to_s else cols = (scale_y * (cols + 0.5)).round rows = (scale_y * (rows + 0.5)).round cmd.resize "x#{rows}" end end cmd.gravity gravity cmd.background "rgba(255,255,255,0.0)" cmd.extent "#{width}x#{height}" if cols != width || rows != height end end
Private Instance Methods
Montage Collage - setting images geometry for rows 1 row - 3 images 2 row - 4 images 3 row - 3 images
@param [Hash] opts @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
@return [String] images geometry
# File lib/FlickrCollage.rb, line 357 def montage_geometry(opts = {}) case opts[:row] when 1, 3 then "#{@img_width}x#{@img_height}+0+0" when 2 then "#{@img_width * 0.75}x#{@img_height}+0+0" when 4 then "#{@img_width * 3}x#{@img_height}+0+0" end end
Montage Collage - setting images paths for rows 1 row - 3 images 2 row - 4 images 3 row - 3 images
@param [Hash] opts @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
@return [String] images path
# File lib/FlickrCollage.rb, line 391 def montage_img_path(opts = {}) case opts[:row] when 1..3 then "#{@img_path}tmp/#{@collage_file}-#{opts[:row]}.jpg" when 4 then "#{@img_path}#{@collage_file}.jpg" else "" end end
Montage Collage - resizing images for rows 1 row - 3 images 2 row - 4 images 3 row - 3 images
@param [Hash] opts @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
@return [Array<String>] Array of file paths for resized images
# File lib/FlickrCollage.rb, line 325 def montage_resize(opts = {}) files = [] case opts[:row] when 1 (0..2).each do |i| files << resize(file: opts[:files][i]) end when 2 (3..6).each do |i| files << resize(file: opts[:files][i], width: @img_width * 0.75) end when 3 (7..9).each do |i| files << resize(file: opts[:files][i]) end when 4 (1..3).each do |i| files << "#{@img_path}tmp/#{@collage_file}-#{i}.jpg" end end files end
Montage Collage - setting images tile for rows 1 row - 3 images 2 row - 4 images 3 row - 3 images
@param [Hash] opts @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
@return [String] images tile
# File lib/FlickrCollage.rb, line 374 def montage_tile(opts = {}) case opts[:row] when 1, 3 then "3x1" when 2 then "4x1" when 4 then "1x3" end end