Reputation: 7308
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?
Upvotes: 2
Views: 3378
Reputation: 1105
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
Upvotes: 2
Reputation: 6659
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)
Upvotes: 5
Reputation: 7308
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.
Upvotes: 3
Reputation: 1510
Maybe there's something wrong with the form? You can consult with Rails Guide here:
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!
Upvotes: 1