Created
July 29, 2012 14:35
-
-
Save stanislaw/3199258 to your computer and use it in GitHub Desktop.
Ruby-vips vs Oil
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 '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 |
I was running fast, so It could be a mistake somewhere, please check the overall code.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Gists act like a common git repositories.
You need to fork this gist and run (replace with your numbers)