Search code examples
rubyimage-processingrmagick

Reducing RGB color intensity in Ruby with Rmagick


I'm translating a function made with MATLAB that reduces the color intensity from an image's sector to Ruby using Rmagick

for i=round(f/3):f 
        for j=1:round(c)
            for k=1:p
            A(i,j,k) = B(i,j,k) - a;
            end
        end
    end

    for i=1:round(2*f/3)

This reduces the color intensity of all 3 RGB matrix by some value (a). Trying to reproduce this with ruby code yielded this:

(0..imagen.columns).each do |x|
  ((2 * imagen.rows) / 3..imagen.rows).each do |y|
    imagen.pixel_color(x, y, 'pink')
  end
end

I can change the lower third of my image to a set color, in this example, to pink.

Trying to reduce each component by some value (atenuacion) with each color's method won't work, it returns the same image.

(0..imagen.columns).each do |x|
  ((2 * imagen.rows) / 3..imagen.rows).each do |y|
    pixel = imagen.pixel_color(x, y)
    pixel.red - atenuacion
    pixel.green - atenuacion
    pixel.blue - atenuacion
    imagen.pixel_color(x, y, pixel)
  end
end

Any tips or suggestions are welcome, thank you in advance :D


Solution

  • The problem is here:

    pixel.red - atenuacion
    pixel.green - atenuacion
    pixel.blue - atenuacion
    

    You're not changing the value of pixel.red, etc. You're just subtracting atenuacion from the value of pixel.red and then doing nothing with the result. Try this:

    pixel.red -= atenuacion
    pixel.green -= atenuacion
    pixel.blue -= atenuacion
    

    In the above, pixel.red -= atenuacion is shorthand for pixel.red = pixel.red - atenuacion. I'm just guessing that pixel.red et al are setters as well as getters. If not, you may need to do something like this instead:

    pixel = imagen.pixel_color(x, y)
    
    new_color = Magick::Pixel.new(
                  pixel.red - atenuacion,
                  pixel.green - atenuacion,
                  pixel.blue - atenuacion,
                  pixel.opacity)
    
    imagen.pixel_color(x, y, new_color)