7

I am completely new to image processing. I know nothing about what is JPEG internally and how it works.

I wonder, if I can find somewhere piece of ruby code performing following simple operation:

  1. Open jpeg file.
  2. Iterate through each pixel and set it's color to fx green.
  3. Write result to another file.

I am especially interested in how this can be accomplished using ruby-vips library
https://github.com/ender672/ruby-vips

My goal - to learn how to perform basic image processing operations using ruby-vips (gamma correction, brightness, tint, ...)

Any links to working examples more complex than 'hello world'-like one on ruby-vips's github page would be highly appreciated!

If there are alternatives to ruby-vips, I would be thankful for them too.


UPDATE

Much has happened since I asked this question:

jcupitt
  • 10,213
  • 2
  • 23
  • 39
Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
  • ruby-vips looks abandoned on github. Keep that in mind, especially if you want to use later versions of ruby. – d11wtq May 22 '12 at 23:31
  • Working tree is on https://github.com/jcupitt/ruby-vips. Also ruby-vips was released at rubygems: http://rubygems.org/gems/ruby-vips – Stanislav Pankevich Jun 22 '12 at 14:54
  • thanks. Actually looks pretty good. Will have to have a play around with it. We really need something that allows drawing onto a canvas too (currently we're leaning towards Cairo for that)... I wish there was more available (like this) when it comes to image processing in ruby. – d11wtq Jun 22 '12 at 15:14

2 Answers2

10

update ruby-vips has changed a bit since this answer was written. I've revised it for the current (2018) version.

I'm one of the maintainers of libvips, the image processing library that ruby-vips wraps.

Tim's ruby-vips repository hasn't been touched for a while. I have a fork here that works with current libvips:

https://github.com/jcupitt/ruby-vips

There are some examples here:

https://github.com/jcupitt/ruby-vips/tree/master/example

To set the red and blue channels to zero and just leave a green image you might multiply R and B by zero and G by 1. ruby-vips uses arrays to represent pixel constants, so you can just write:

out = in * [0, 1, 0]

A complete runnable example might be:

#!/usr/bin/ruby

require 'vips'

im = Vips::Image.new_from_file '/home/john/pics/theo.jpg'
im *= [0, 1, 0]
im.write_to_file 'x.jpg'

There's a trick you can use for new_from_file: if you know you will just be doing simple top-to-bottom operations on the image, like arithmetic or filtering or resize, you can tell ruby-vips that you only need sequential access to pixels:

im = Vips::Image.new_from_file '/home/john/pics/theo.jpg', access: :sequential

Now ruby-vips will stream your image. It'll run the load, the multiply and the save all in parallel and never keep more than a few scanlines of pixels in memory at any one time. This can give a really nice improvement to speed and memory use.

To change image gamma you might try something like:

im = im ** 0.5 * 255 / 255 ** 0.5

Though that'll be a bit slow (it'll call pow() three times for each pixel), it'd be much faster to make a lookup table, run the pow() on that, then map the image through the table:

lut = Vips::Image.identity
lut = lut ** 0.5 * 255 /255 ** 0.5
im = im.maplut lut

Any questions, please feel free to open them on the rubyvips issue tracker:

https://github.com/jcupitt/ruby-vips/issues

jcupitt
  • 10,213
  • 2
  • 23
  • 39
  • 4
    Regarding ruby-vips vs. RMagick: vips' advantages would be much lower memory use (by a factor of 100 on the benchmark above, for example), much faster (a factor of 5 on that benchmark) and a larger, more flexible range of image processing operations and pixel formats (rmagick only supports 1 - 5 image channels, for example, and struggles with floating point images). rmagicks advantages would be wide usage, much more comprehensive documentation, and a set of built-in operations that match common use cases (for example, vips has no built-in porter-duff compositing, you need to roll your own). – jcupitt May 23 '12 at 10:50
  • I might have to look into patching CarrierWave to use this as an alternative to RMagick. I don't hold much love for RMagick and this looks better, thanks. – d11wtq Jun 22 '12 at 15:19
2

I'm sorry I don't know ruby-vips, but ImageMagick is a classic when it comes to image processing. There are Ruby bindings in the form of RMagick (current repo), and you can derive a lot of functionality from the ImageMagick docs, but there are also three tutorials here, as well as a lot of examples on the web.

If you really want to go deep into the theory of image processing, which in its roots is a form of signal processing (this is totally exciting and rewarding as it often allows you to apply very similar algorithms on images and audio/video signals, but it will ultimately get very heavy on math - Fourier transforms), then, if mathematics don't scare you, I can only recommend to read the book by Gonzalez and Woods, I would say it's the definite reference in this field. It's expensive, but there's all you need in there to get you started and well beyond. Here's also a page with links to free ebooks if you would like to get started without spending lots of money first.

emboss
  • 38,880
  • 7
  • 101
  • 108