Skip to content

Questions and/or issues - comparision with rmagick #230

@noraj

Description

@noraj

I wanted to replace rmagick with ruby-vips as it's claimed that rmagick have large memory footprint and that ruby-vips is faster.

  1. It's was hard to figure only by reading the API documentation that I had to use black and draw_point methods. Especially for black, I expected a new(w,h) method for Vips::Image like there are new_from_xxx methods.

  2. The draw_point is a special case of draw_rect (virtually declared). It's said that the parameter ink is the Color for pixels of type Array<Double>. By finding a example on internet I saw either a RGB array or RGBA array. There is no more information in the doc of what "ink" is and which format is expected. By providing an RGB array the resulting image is black and white instead of the orange and blue colors provided.

  3. The README claims that ruby-vips is way faster than rmagick but looking at a becnhmark, rmagick generate the image in 0.04 sec and ruby-vips in more than 21 sec. Am I doing something wrong?

  4. On rmagick the methods are applying the the object directly, on ruby-vips all methods returns an object so we have to do obj = obj.method as there is no obj.method! self applying methods. This is less convenient to write and I'm wondering if all the object copies are the reason ruby-vips is slower, because it is generating 10000 images instead of modifying 10000 pixels of one image.

require 'rmagick'
require 'vips'
require 'benchmark'

data = (0..10000).map {|_i| rand(2) }

width = 100
height = 100

Benchmark.bm do |x|

  x.report {
    img = Magick::Image.new(width, height)
    i = 0
    (0...width).each do |x|
      (0...height).each do |y|
        # orange (0)
        img.pixel_color(x, y, "rgb(255,66,14)")
        # blue (1)
        img.pixel_color(x, y, "rgb(0,69,134)") if data[i] == true or data[i] == 1
        i+=1
      end
    end
    img.write('pixel.png')
  }

  x.report {
    im = Vips::Image.black(width, height)
    i = 0
    (0...width).each do |x|
      (0...height).each do |y|
        # orange (0)
        im = im.draw_point([255,66,14], x, y)
        # blue (1)
        im = im.draw_point([0,69,134], x, y) if data[i] == true or data[i] == 1
        i+=1
      end
    end
    im.write_to_file('pixel.png')
  }

end
$ ruby poc.rb
       user     system      total        real
   0.046996   0.000009   0.047005 (  0.056036)
 21.284349   3.246679  24.531028 ( 23.375003)

Is there a better way to do it with new_from_array ?

Versions

ffi 1.12.2
ruby-vips 2.0.17
rmagick 4.1.1
imagemagick 7.0.10.6
libvips 8.9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions