You've already forked image_processing
mirror of
https://github.com/usetrmnl/image_processing.git
synced 2026-04-29 13:33:11 -07:00
- Added ruby-vips gem
- [MISSING] some commands
This commit is contained in:
@@ -20,5 +20,6 @@ Gem::Specification.new do |spec|
|
||||
spec.add_development_dependency "minitest-hooks"
|
||||
spec.add_development_dependency "minispec-metadata"
|
||||
spec.add_development_dependency "mini_magick", ">= 4.3.5"
|
||||
spec.add_development_dependency "ruby-vips", ">= 2.0.0"
|
||||
spec.add_development_dependency "phashion" unless RUBY_ENGINE == "jruby"
|
||||
end
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
require "image_processing/version"
|
||||
require "vips"
|
||||
require "tempfile"
|
||||
|
||||
module ImageProcessing
|
||||
module Vips
|
||||
module_function
|
||||
|
||||
def convert!(image, format, page = nil, &block)
|
||||
with_ruby_vips(image) do |img|
|
||||
tmp_name = tmp_name(image.path, "_tmp.#{format}")
|
||||
img.write_to_file(tmp_name)
|
||||
tmp_name
|
||||
end
|
||||
end
|
||||
|
||||
def auto_orient!(image)
|
||||
with_ruby_vips(image) do |img|
|
||||
img.autorot
|
||||
tmp_name = tmp_name(image.path)
|
||||
img.write_to_file(tmp_name)
|
||||
tmp_name
|
||||
end
|
||||
end
|
||||
|
||||
def resize_to_limit!(image, width, height)
|
||||
with_ruby_vips(image) do |img|
|
||||
img = resize_image(img, width, height) if width < img.width || height < img.height
|
||||
tmp_name = tmp_name(image.path)
|
||||
img.write_to_file(tmp_name)
|
||||
tmp_name
|
||||
end
|
||||
end
|
||||
|
||||
def resize_to_fit!(image, width, height)
|
||||
with_ruby_vips(image) do |img|
|
||||
img = resize_image(img, width, height)
|
||||
tmp_name = tmp_name(image.path)
|
||||
img.write_to_file(tmp_name)
|
||||
tmp_name
|
||||
end
|
||||
end
|
||||
# Convert an image into a MiniMagick::Image for the duration of the block,
|
||||
# and at the end return a File object.
|
||||
def with_ruby_vips(image)
|
||||
image = ::Vips::Image.new_from_file image.path
|
||||
file_path = yield image
|
||||
File.new(file_path)
|
||||
end
|
||||
|
||||
# Creates a copy of the file and stores it into a Tempfile. Works for any
|
||||
# IO object that responds to `#read(length = nil, outbuf = nil)`.
|
||||
def _copy_to_tempfile(file)
|
||||
extension = File.extname(file.path) if file.respond_to?(:path)
|
||||
tempfile = Tempfile.new(["vips", extension.to_s], binmode: true)
|
||||
IO.copy_stream(file, tempfile.path)
|
||||
file.rewind
|
||||
tempfile
|
||||
end
|
||||
|
||||
def tmp_name(path, ext='_tmp\1')
|
||||
ext_regex = /(\.[[:alnum:]]+)$/
|
||||
path.sub(ext_regex, ext)
|
||||
end
|
||||
|
||||
def resize_image(image, width, height, min_or_max = :min)
|
||||
ratio = get_ratio image, width, height, min_or_max
|
||||
return image if ratio == 1
|
||||
image = if ratio > 1
|
||||
image.resize(ratio, kernel: :nearest)
|
||||
else
|
||||
image.resize(ratio, kernel: :cubic)
|
||||
end
|
||||
image
|
||||
end
|
||||
|
||||
def get_ratio(image, width,height, min_or_max = :min)
|
||||
width_ratio = width.to_f / image.width
|
||||
height_ratio = height.to_f / image.height
|
||||
[width_ratio, height_ratio].send(min_or_max)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,92 @@
|
||||
require "test_helper"
|
||||
require "mini_magick"
|
||||
require "image_processing/vips"
|
||||
require "stringio"
|
||||
|
||||
describe ImageProcessing::Vips do
|
||||
include ImageProcessing::Vips
|
||||
|
||||
def assert_similar(expected, actual)
|
||||
return if RUBY_ENGINE == "jruby"
|
||||
|
||||
a = Phashion::Image.new(expected.path)
|
||||
b = Phashion::Image.new(actual.path)
|
||||
|
||||
distance = a.distance_from(b).abs
|
||||
|
||||
assert_operator distance, :<, 2
|
||||
end
|
||||
|
||||
def assert_dimensions(dimensions, file)
|
||||
assert_equal dimensions, MiniMagick::Image.new(file.path).dimensions
|
||||
end
|
||||
|
||||
def assert_type(type, file)
|
||||
assert_equal type, MiniMagick::Image.new(file.path).type
|
||||
end
|
||||
|
||||
def assert_resolution(resolution, file)
|
||||
actual_resolution = MiniMagick::Image.new(file.path).resolution
|
||||
# Travis has old imagemagick version
|
||||
actual_resolution = actual_resolution.select(&:nonzero?) if ENV["CI"]
|
||||
assert_equal resolution, actual_resolution
|
||||
end
|
||||
|
||||
def fixture_image(name)
|
||||
File.open("test/fixtures/#{name}")
|
||||
end
|
||||
|
||||
before do
|
||||
@portrait = _copy_to_tempfile(fixture_image("portrait.jpg"))
|
||||
@landscape = _copy_to_tempfile(fixture_image("landscape.jpg"))
|
||||
end
|
||||
|
||||
|
||||
describe "#convert!" do
|
||||
it "changes the image format" do
|
||||
result = convert!(@portrait, "png")
|
||||
assert_type "PNG", result
|
||||
end
|
||||
end
|
||||
|
||||
describe "#auto_orient!" do
|
||||
it "fixes the orientation of the image" do
|
||||
result = auto_orient!(@portrait)
|
||||
assert_equal "1", MiniMagick::Image.new(result.path).exif["Orientation"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#resize_to_limit!" do
|
||||
it "resizes the image up to a given limit" do
|
||||
result = resize_to_limit!(@portrait, 400, 400)
|
||||
assert_dimensions [300, 400], result
|
||||
end
|
||||
|
||||
it "does not resize the image if it is smaller than the limit" do
|
||||
result = resize_to_limit!(@portrait, 1000, 1000)
|
||||
assert_dimensions [600, 800], result
|
||||
end
|
||||
|
||||
it "produces correct image" do
|
||||
result = resize_to_limit!(@portrait, 400, 400)
|
||||
assert_similar fixture_image("limit.jpg"), result
|
||||
end
|
||||
end
|
||||
|
||||
describe "#resize_to_fit!" do
|
||||
it "resizes the image to fit given dimensions" do
|
||||
result = resize_to_fit!(@portrait, 400, 400)
|
||||
assert_dimensions [300, 400], result
|
||||
end
|
||||
|
||||
it "enlarges image if it is smaller than given dimensions" do
|
||||
result = resize_to_fit!(@portrait, 1000, 1000)
|
||||
assert_dimensions [750, 1000], result
|
||||
end
|
||||
|
||||
it "produces correct image" do
|
||||
result = resize_to_fit!(@portrait, 400, 400)
|
||||
assert_similar fixture_image("fit.jpg"), result
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user