Class: Blufin::Image
- Inherits:
-
Object
- Object
- Blufin::Image
- Defined in:
- lib/core/image.rb
Constant Summary collapse
- VALID_SIDES =
%w(width height)
Class Method Summary collapse
-
.add_text(src, target, text, x = 35, y = 60, bg = 'black', fg = 'white', point_size = 22, stroke_width = 1) ⇒ Object
Adds text/caption to image.
-
.calc_aspect_ratio(width, height) ⇒ Object
Calculates the aspect ration (IE: 16:9) from a set of given dimensions.
-
.calc_file_name(prefix, ext, side, length, ratio) ⇒ Object
Standardizes the way output files are named.
-
.calc_height_from_ratio(ratio, width) ⇒ Object
Calculates height from aspect ratio and width: IE: 16:9 and 1920 returns -> 1080.
-
.calc_width_from_ratio(ratio, height) ⇒ Object
Calculates width from aspect ratio and height: IE: 16:9 and 1080 returns -> 1920.
-
.crop_to_length_and_ratio(src, target, side, length, ratio, quality = 100) ⇒ Object
This command crops an image based on a give size and a ration (using ImageMagick).
-
.gcd(a, b) ⇒ Object
Gets the greatest-common-denominator.
-
.info(path_and_file) ⇒ Object
Uses ImageMagick to return details about an image.
Class Method Details
permalink .add_text(src, target, text, x = 35, y = 60, bg = 'black', fg = 'white', point_size = 22, stroke_width = 1) ⇒ Object
Adds text/caption to image.
85 86 87 88 89 90 91 92 |
# File 'lib/core/image.rb', line 85 def self.add_text(src, target, text, x = 35, y = 60, bg = 'black', fg = 'white', point_size = 22, stroke_width = 1) raise RuntimeError, "File not found: #{src}" unless Blufin::Files::file_exists(src) raise RuntimeError, "Expected integer (for x), instead got: #{x}" unless x.to_s =~ /^\d+$/ raise RuntimeError, "Expected integer (for y), instead got: #{y}" unless y.to_s =~ /^\d+$/ raise RuntimeError, "Expected integer (for point_size), instead got: #{point_size}" unless point_size.to_s =~ /^\d+$/ raise RuntimeError, "Expected integer (for stroke_width), instead got: #{stroke_width}" unless stroke_width.to_s =~ /^\d+$/ Blufin::Terminal::execute("convert #{src} -undercolor #{bg} -stroke #{fg} -pointsize #{point_size} -strokewidth #{stroke_width} -draw \"text #{x},#{y} '#{text}'\" #{target}") end |
permalink .calc_aspect_ratio(width, height) ⇒ Object
Calculates the aspect ration (IE: 16:9) from a set of given dimensions.
96 97 98 99 |
# File 'lib/core/image.rb', line 96 def self.calc_aspect_ratio(width, height) gcd = gcd(width, height) "#{(width / gcd).to_i}:#{(height / gcd).to_i}" end |
permalink .calc_file_name(prefix, ext, side, length, ratio) ⇒ Object
Standardizes the way output files are named.
133 134 135 136 137 138 139 140 |
# File 'lib/core/image.rb', line 133 def self.calc_file_name(prefix, ext, side, length, ratio) raise RuntimeError, "Expected integer, instead got: #{length}" unless length.to_s =~ /^\d+$/ raise RuntimeError, "Expected one of: #{VALID_SIDES.inspect}, instead got: #{side}" unless VALID_SIDES.include?(side) raise RuntimeError, "Unexpected ratio #{Blufin::Terminal::format_highlight(ratio)}, expected something like: 16:9" unless ratio =~ /\d{1,2}:\d{1,2}/ x = side == 'width' ? length : calc_width_from_ratio(ratio, length) y = side == 'width' ? calc_height_from_ratio(ratio, length) : length "#{prefix}-#{x}x#{y}.#{ext.downcase}" end |
permalink .calc_height_from_ratio(ratio, width) ⇒ Object
Calculates height from aspect ratio and width: IE: 16:9 and 1920 returns -> 1080.
114 115 116 117 118 119 |
# File 'lib/core/image.rb', line 114 def self.calc_height_from_ratio(ratio, width) raise RuntimeError, "Unexpected ratio #{Blufin::Terminal::format_highlight(ratio)}, expected something like: 16:9" unless ratio =~ /\d{1,2}:\d{1,2}/ raise RuntimeError, "Expected integer, instead got: #{width}" unless width.to_s =~ /^\d+$/ rs = ratio.split(':') ((width.to_i / rs[0].to_i) * rs[1].to_i).to_i end |
permalink .calc_width_from_ratio(ratio, height) ⇒ Object
Calculates width from aspect ratio and height: IE: 16:9 and 1080 returns -> 1920.
104 105 106 107 108 109 |
# File 'lib/core/image.rb', line 104 def self.calc_width_from_ratio(ratio, height) raise RuntimeError, "Unexpected ratio #{Blufin::Terminal::format_highlight(ratio)}, expected something like: 16:9" unless ratio =~ /\d{1,2}:\d{1,2}/ raise RuntimeError, "Expected integer, instead got: #{height}" unless height.to_s =~ /^\d+$/ rs = ratio.split(':') ((height.to_i / rs[1].to_i) * rs[0].to_i).to_i end |
permalink .crop_to_length_and_ratio(src, target, side, length, ratio, quality = 100) ⇒ Object
This command crops an image based on a give size and a ration (using ImageMagick). If dimensions don’t match ratio, adjusts accordingly and crops from center. Must specify if you want @side to be width or height, where your chosen side will match @length and the other gets altered as needed. side - the side for which you want to apply the length to (other side will get adjusted accordingly) length - the length that you want applied ratio - the ratio you want (16:9 and 9:16 will produce different results) quality - the higher the quality, the bigger the image.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/core/image.rb', line 40 def self.crop_to_length_and_ratio(src, target, side, length, ratio, quality = 100) d1 = length side.downcase! raise RuntimeError, "Expected integer, instead got: #{d1}" unless d1.to_s =~ /^\d+$/ raise RuntimeError, "Expected one of: #{VALID_SIDES.inspect}, instead got: #{side}" unless VALID_SIDES.include?(side) raise RuntimeError, "Unexpected ratio #{Blufin::Terminal::format_highlight(ratio)}, expected something like: 16:9" unless ratio =~ /\d{1,2}:\d{1,2}/ raise RuntimeError, "Expected integer between 0 - 100, instead got: #{quality}" unless quality.to_s =~ /^\d+$/ && quality.to_i >= 0 && quality.to_i <= 100 raise RuntimeError, "File not found: #{src}" unless Blufin::Files::file_exists(src) # Convert the initial image to match the width. c1 = side == 'width' ? d1 : "x#{d1}" Blufin::Terminal::execute("magick #{src} -resize #{c1} -quality #{quality} #{target}") ac = info(target) d2 = side == 'width' ? calc_height_from_ratio(ratio, d1) : calc_width_from_ratio(ratio, d1) # If the other side is less that what's desired, convert the image using the other orientation. c3 = side == 'width' ? ac.height : ac.width if c3 < d2 c2 = side == 'width' ? "x#{d2}" : d2 Blufin::Terminal::execute("magick #{src} -resize #{c2} -quality #{quality} #{target}") ac = info(target) end ow = ac.width oh = ac.height if side == 'width' x = ow > d1 ? ((ow - d1) / 2).to_i : 0 y = oh > d2 ? ((oh - d2) / 2).to_i : 0 c4 = d1 c5 = calc_height_from_ratio(ratio, d1) else x = ow > d2 ? ((ow - d2) / 2).to_i : 0 y = oh > d1 ? ((oh - d1) / 2).to_i : 0 c4 = calc_width_from_ratio(ratio, d1) c5 = d1 end # Do the final crop. Blufin::Terminal::execute("convert #{target} -crop #{c4}x#{c5}+#{x}+#{y} +repage #{target}") # Output details about the image. img = info(target) ts = target.split('/') puts puts " \x1B[38;5;40m#{ts[ts.length - 1]}\x1B[38;5;240m \xe2\x80\x94 #{Filesize.from("#{img.size} B").pretty} | #{img.ratio}#{img.ratio != ratio ? ' - For this image, a perfect ratio couldn\'t be achieved :(' : nil}\x1B[0m" puts end |
permalink .gcd(a, b) ⇒ Object
Gets the greatest-common-denominator. Used to calculate screen aspect ratio. See: stackoverflow.com/questions/14731745/what-exactly-does-do-in-javascript
124 125 126 127 128 129 |
# File 'lib/core/image.rb', line 124 def self.gcd(a, b) a = a.to_i b = b.to_i return a if b == 0 gcd(b, a % b) end |
permalink .info(path_and_file) ⇒ Object
Uses ImageMagick to return details about an image.
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/core/image.rb', line 16 def self.info(path_and_file) check_image_magick_installed raise RuntimeError, "File not found: #{path_and_file}" unless Blufin::Files::file_exists(path_and_file) img = MiniMagick::Image.open(path_and_file) img_container = ImageContainer.new img_container.width = img.dimensions[0].to_i img_container.height = img.dimensions[1].to_i img_container.size = img.size img_container.size_human = img.human_size img_container.type = img.type.downcase img_container.ratio = calc_aspect_ratio(img.dimensions[0].to_i, img.dimensions[1].to_i) img_container end |