Last active
June 11, 2018 17:15
-
-
Save joaocarmo/f4ae7125edad7661da75afddb84d87f2 to your computer and use it in GitHub Desktop.
Using Ruby's RMagick to process (crop and/or resize) an image given simple inputs (new ratio/size)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| require "rmagick" | |
| # Define class UniformImage | |
| class UniformImage | |
| def initialize(image, suffix="_uniform", extension="jpg") | |
| # Instance variables | |
| @image = image | |
| if self.exists? | |
| @image_open = Magick::Image::read(@image).first | |
| else | |
| @image_open = Magick::Image::new(100, 100) | |
| end | |
| @image_processed = @image_open | |
| @image_suffix = suffix | |
| @image_extension = extension | |
| end | |
| def exists? | |
| File.file?(@image) | |
| end | |
| def print_info | |
| puts @image | |
| @image_open = Magick::Image::read(@image).first | |
| puts " Format: #{@image_open.format}" | |
| puts " Geometry: #{@image_open.columns}x#{@image_open.rows}" | |
| puts " Class: " + case @image_open.class_type | |
| when Magick::DirectClass | |
| "DirectClass" | |
| when Magick::PseudoClass | |
| "PseudoClass" | |
| end | |
| puts " Depth: #{@image_open.depth} bits-per-pixel" | |
| puts " Colors: #{@image_open.number_colors}" | |
| puts " Filesize: #{@image_open.filesize}" | |
| puts " Resolution: #{@image_open.x_resolution.to_i}x#{@image_open.y_resolution.to_i} "+ | |
| "pixels/#{@image_open.units == Magick::PixelsPerInchResolution ? | |
| "inch" : "centimeter"}" | |
| end | |
| def columns | |
| @image_processed.columns.to_f | |
| end | |
| def rows | |
| @image_processed.rows.to_f | |
| end | |
| def orientation | |
| # 0 Portrait | |
| # 1 Landscape | |
| self.columns() > self.rows() ? 0 : 1 | |
| end | |
| def aspect_ratio | |
| self.columns() / self.rows() | |
| end | |
| def crop_to_aspect_ratio(new_ratio) | |
| new_ratio_arr = new_ratio.split(":") | |
| cols = new_ratio_arr[0].to_f | |
| rows = new_ratio_arr[1].to_f | |
| r2 = cols / rows | |
| x1 = self.columns() | |
| y1 = self.rows() | |
| r1 = self.aspect_ratio | |
| if r1 < r2 | |
| x2 = x1 | |
| y2 = (y1 * r1 / r2).ceil | |
| else | |
| x2 = (x1 * r2 / r1).ceil | |
| y2 = y1 | |
| end | |
| @image_processed = @image_processed.crop(Magick::CenterGravity, x2, y2, true) | |
| end | |
| def resize(new_size) | |
| new_size_arr = new_size.split("x") | |
| cols = new_size_arr[0].to_f | |
| rows = new_size_arr[1].to_f | |
| @image_processed = @image_processed.resize_to_fit(cols, rows) | |
| end | |
| def crop_and_resize(new_size) | |
| new_size_arr = new_size.split("x") | |
| cols = new_size_arr[0].to_f | |
| rows = new_size_arr[1].to_f | |
| new_ratio = "#{cols}:#{rows}" | |
| self.crop_to_aspect_ratio(new_ratio) | |
| self.resize(new_size) | |
| end | |
| def new_name | |
| name = @image.split(".") | |
| filename = name[0] | |
| extension = @image_extension || name[1] || "jpg" | |
| "#{filename}#{@image_suffix}.#{extension}" | |
| end | |
| def save | |
| @image_processed.write(self.new_name) | |
| end | |
| end | |
| # Examples | |
| me = UniformImage.new("example.jpg") | |
| me.crop_to_aspect_ratio("3:2") | |
| me.resize("300x300") | |
| me.save() | |
| her = UniformImage.new("example2.jpg") | |
| her.crop_to_aspect_ratio("2:3") | |
| her.resize("300x300") | |
| her.save() | |
| him = UniformImage.new("example3.jpg") | |
| him.crop_and_resize("200x300") | |
| him.save() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment