-
-
Save jcupitt/3304701 to your computer and use it in GitHub Desktop.
Ruby-vips vs Oil
This file contains 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 'rubygems' | |
gem 'ruby-vips' | |
gem 'oil' | |
require 'vips' | |
require 'oil' | |
require 'benchmark' | |
require 'stringio' | |
module Procedure | |
NUMBER = 1 | |
IM_SIZE = 100 | |
class << self | |
def run processor, img, best_of | |
result = nil | |
result = Benchmark.bmbm do |b| | |
(1 .. best_of).each do |number| | |
b.report number.to_s do | |
NUMBER.times do | |
send processor, img | |
end | |
end | |
end | |
end | |
output result | |
end | |
def output result | |
result = (result.map(&:to_a).map{|el| el[5]}.min * 1000).to_i | |
"#{result}ms" | |
end | |
class VipsProcessor | |
HIGH_QUALITY = false | |
SHARPEN_MASK = begin | |
conv_mask = [ | |
[ -1, -1, -1 ], | |
[ -1, 24, -1 ], | |
[ -1, -1, -1 ] | |
] | |
::VIPS::Mask.new conv_mask, 16 | |
end | |
attr_reader :src, :image | |
def initialize src | |
@src = src | |
resize_to_limit IM_SIZE, IM_SIZE | |
end | |
def resize_to_limit(new_width, new_height) | |
manipulate! do |image| | |
image = resize_image(image,new_width,new_height) if new_width < image.x_size || new_height < image.y_size | |
image | |
end | |
end | |
def manipulate! | |
@image ||= VIPS::Image.new(src) | |
@image = yield @image | |
rescue => e | |
raise("Failed to manipulate file, maybe it is not an image? Original Error: #{e}") | |
end | |
def resize_image(image, width, height, min_or_max = :min) | |
ratio = get_ratio image, width, height, min_or_max | |
if jpeg? # find the shrink ratio for loading | |
shrink_factor = [8, 4, 2, 1].find {|sf| 1.0 / ratio >= sf } | |
shrink_factor = 1 if shrink_factor == nil | |
image = VIPS::Image.jpeg src, | |
:shrink_factor => shrink_factor, :sequential => true | |
ratio = get_ratio image, width, height, min_or_max | |
elsif png? | |
image = VIPS::Image.png src, :sequential => true | |
end | |
if ratio > 1 | |
image = image.affinei_resize :nearest, ratio | |
else | |
if HIGH_QUALITY | |
if ratio <= 0.5 | |
factor = (1.0 / ratio).floor | |
puts "int shrink by factor = #{factor}" | |
image = image.shrink(factor) | |
image = image.tile_cache(image.x_size, 1, 10) | |
ratio = get_ratio image, width, height, min_or_max | |
end | |
image = image.affinei_resize :bilinear, ratio | |
image = image.conv SHARPEN_MASK | |
else | |
image = image.affinei_resize :nearest, ratio | |
end | |
end | |
image | |
end | |
def get_ratio(image, width,height, min_or_max = :min) | |
width_ratio = width.to_f / image.x_size | |
height_ratio = height.to_f / image.y_size | |
[width_ratio, height_ratio].send(min_or_max) | |
end | |
def jpeg?(path = src) | |
path =~ /.*jpg$/i or path =~ /.*jpeg$/i | |
end | |
def png?(path = src) | |
path =~ /.*png$/i | |
end | |
end | |
def vips_jpg src | |
processor = VipsProcessor.new(src) | |
output = processor.resize_to_limit IM_SIZE, IM_SIZE | |
output.jpeg("vips.#{src}") | |
end | |
def vips_png src | |
processor = VipsProcessor.new(src) | |
output = processor.resize_to_limit IM_SIZE, IM_SIZE | |
output.png("vips.#{src}") | |
end | |
def oil_jpg src | |
jpeg = Oil::JPEG.new(im(src), IM_SIZE, IM_SIZE) | |
File.open("oil.#{src}", 'wb') do |f| | |
jpeg.each { |data| f << data } | |
end | |
end | |
def oil_png src | |
png = Oil::PNG.new(im(src), IM_SIZE, IM_SIZE) | |
File.open("oil.#{src}", 'wb') do |f| | |
png.each { |data| f << data } | |
end | |
end | |
def im src | |
File.open src, 'rb' | |
end | |
end | |
end | |
best_of = 1 | |
#result_vips_jpg = Procedure.run :vips_jpg, "peacock.jpg", best_of | |
result_vips_jpg = Procedure.run :vips_jpg, "wtc.jpg", best_of | |
result_vips_png = Procedure.run :vips_png, "peacock.png", best_of | |
#result_oil_jpg = Procedure.run :oil_jpg, "peacock.jpg", best_of | |
result_oil_jpg = Procedure.run :oil_jpg, "wtc.jpg", best_of | |
result_oil_png = Procedure.run :oil_png, "peacock.png", best_of | |
puts "Ruby-vips #{VIPS::VERSION} built against libvips #{VIPS::LIB_VERSION}" | |
print "ruby-vips, jpeg image: " | |
puts result_vips_jpg | |
print "ruby-vips, png image: " | |
puts result_vips_png | |
print "oil, jpeg image: " | |
puts result_oil_jpg | |
print "oil, png image: " | |
puts result_oil_png |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment