سؤال

In my Rails app, I have a form that allows users to upload images. My app is supposed to resize the images with the following controller method. (POST to this method, params[:file] contains the ActionDispatch::Http::UploadedFile that was uploaded:

 def resize_and_store
    file = params[:file]

    # resize image
    Magick::Image.read(file.tempfile).first
    newimg = image.resize(100,100)

    #etc... Store newimg
  end

I get the following error, on the line that says Image.read:

Magick::ImageMagickError (no decode delegate for this image format `0xb9f6052c>' @ error/constitute.c/ReadImage/544):

Testing this with an uploaded PNG file, it seems RMagick doesn't pick up that the temporary file is a PNG file. The code above does work if I read a locally stored PNG file, so it can't be that I'm missing the PNG decoder. How can I fix this and why does this happen?

هل كانت مفيدة؟

المحلول

You can do from_blob on a ActionDispatch::Http::UploadedFile param (this is how a file comes in):

images = Magick::Image.from_blob(params[:file].read)

نصائح أخرى

Storing the file temporarily will solve the problem:

open('temp.png', 'wb') do |file|
  file << uploaded.tempfile.read
end
images=Magick::Image.read('temp.png')

Probably wise to check input size as well.

Alternatively, parse the image from a blob.

Using the answer by @joost (or similar approach) really helped to point me in the right direction but it didn't work on the second attempt with the same temp file - my use case was creating multiple image types from the tempfile source. This is what I've used, wrapping in a File.open block so we don't leak the file descriptor:

File.open(tempfile, "rb") do |f|
  img = Magick::Image::from_blob(f.read).first
  resized = img.resize_to_fit(w, h)
  resized.write(dest)
  resized.destroy!
  img.destroy!
end

Maybe there's something wrong with the form? You can consult with Rails Guide here:

Rails Guides: Uploading Files

I think that you may have multipart: true missing in your form declaration. Also, I would strongly advise to use Carrierwave to handle file uploads. Among several things, it will help you to organize your file transformations (putting logic out of the controllers). Here's a railscast about it:

RailsCasts: CarrierWave File Uploads.

Good luck!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top