views:

119

answers:

2

I'm using Dragonfly to generate thumbnail images in a Rails app.

I'm serving all picture images as JPG's. Now the client is uploading transparent PNG files, like this one:

http://www.ibanez.co.jp/products/images/eg2010/ART120_TRF_12_02.png

Dragonfly uses RMagick to convert these images to JPG. The problem is that it converts the PNG images to JPG with a black background, and my site's design requires a white background. I've tried to override it like this:

encoded_image = Magick::Image.from_blob(image.data).first

if encoded_image.format.downcase == format
  image # do nothing
else
  encoded_image.format = format
  encoded_image.background_color = "white"
  encoded_image.transparent_color = "white"
  encoded_image.to_blob
end

But the produced JPG images still contain a black background. Does anyone know how to beat RMagick into using a white background when converting the transparent layer?

I know I could just serve as PNG, but then the images are 10 times as large, and the site is already pretty bandwidth heavy.

A: 

If anyone else has the same problem, I wasn't able to figure out how to do this through RMagick. I've now written a solution using command line ImageMagick (convert):

  if encoded_image.format.downcase == "png"
    temp_file = Tempfile.new(image.object_id)

    encoded_image.write("png:" + temp_file.path)

    encoded_image.destroy!

    system "convert -flatten \"#{temp_file.path}\" \"jpg:#{temp_file.path}\""

    encoded_image = Magick::Image.read(temp_file.path)[0]

    temp_file.delete
  else
Alexander Malfait
+1  A: 

You can create an ImageList to be able to put a white image with the same size as your original image UNDER the transparent picture. If you flatten the ImageList down to an image, you get an image with the transparent color replaced by whatever the second image contained.

img_list = Magick::ImageList.new
img_list.read("my_png_file.png")
img_list.new_image(img_list.first.columns, img_list.first.rows) { self.background_color = "white" } # Create new "layer" with white background and size of original image
image = img_list.reverse.flatten_images

This works for me but could be optimized further, i guess.

Hope that helps! Hendrik

Hendrik
Works like a charm! Sorry for the late accept.
Alexander Malfait