Programming, Software

Bit Depth Problems with RMagick / ImageMagick

I just spent the entire afternoon debugging a problem I couldn’t find elsewhere, so I’m documenting it in the off chance someone else runs into the evil thing.

I’m composing some images on the fly using ImageMagick via RMagic. It grabs one file, floods the image with a given color, and layers another on top of it. Locally, it works great, and gives me “body parts” like this one:

Unfortunately, when I push the code to Heroku, it starts going through a goth phase and filling everything in with BLACK LIKE SOUL:
I spent a very, very long time trying to suss this one out, checking out everything from opacity to gem versions. Finally, I checked the ImageMagick version (Magick::Magick_version).
Local: “ImageMagick 6.6.7-1 2011-02-08 Q8 http://www.imagemagick.org”
Heroku: “ImageMagick 6.6.0-4 2010-06-01 Q16 http://www.imagemagick.org”

Ok, so Heroku’s is a bit older. But that’s not the critical issue. The bigger problem is the Q16, which is reporting the quantum depth. I don’t understand nearly enough about image processing to talk about what that really means. But long story short, it means my images had different default bit depths and it was causing everything to blow up. Or something.

I was able to fix it by changing how I instantiated the Pixel for the fill. Before, I was using

fill_image.colorize(1,1,1,Magick::Pixel.new(r,g,b))

where r, g, and b are integers between 0 and 255.

Conveniently, RMagick has added a from_color method to Pixel, which lets you define a pixel based on a color name. I passed in a hex value, and everything magic(k)ally works normally again:

color = '#ababab'
fill_color = Magick::Pixel.from_color(color.upcase)
fill_image = fill_image.colorize(1,1,1,fill_color)

I wish I understood a few more of the particulars about what is really going on here. But for the time being I need to move on to finishing this up. Any insight is welcome in the comments.