Here's my image model. Perhaps that will give someone some insight.
Say, I'm doing the Magick::Image.from_blob call in #after_save.
Perhaps something weird is happening with @file's lifetime or
something?
class Image < ActiveRecord::Base
belongs_to :house
belongs_to :community
belongs_to :contractor
FileLocation = "#{RAILS_ROOT}/public/media/"
DisplayLocation = "/media"
def file=(file)
if file.size > 0
self.content_type = file.content_type.strip
@file = file
end
end
# Runs after Image is saved, saves the image to the file system.
def after_save
if @file
@magick_image = Magick::Image.from_blob(@file.read).first
save_full_image
save_thumbnail_image
save_rounded_thumbnail_image
save_medium_image
save_large_image
end
end
# If image is already a jpeg, then just write it to a file.
# If it's not, convert it to a jpeg and then write.
def save_full_image
@magick_image.write(full_file)
end
# Write a thumbnail to the filesystem
def save_thumbnail_image
thumbnailed_magick_image = resize_image_to_exact_size(180,135)
thumbnailed_magick_image.write(thumbnail_file)
end
def save_rounded_thumbnail_image
thumbnail_image = resize_image_to_exact_size(180, 135)
color = "#000033"
corner_width = 15
corners = Magick::Draw.new
corners.stroke(color)
corners.fill_opacity(0)
corners.stroke_width(15)
corners.roundrectangle(0, 0,
thumbnail_image.columns, thumbnail_image.rows,
corner_width, corner_width)
corners.draw(thumbnail_image)
thumbnail_image.write(rounded_thumbnail_file)
end
# Resizes a Magick image to an exact size, keeping the same aspect ratio
def resize_image_to_exact_size(width, height)
new_aspect_ratio = width.to_f / height.to_f
old_aspect_ratio = @magick_image.columns.to_f / @magick_image.rows.to_f
if old_aspect_ratio < new_aspect_ratio
# Image too tall, geometry string should restrict height
geometry_string = "#{width}"
else
# Image too wide or just right, geometry string should
# restrict width
geometry_string = "x#{height}"
end
# Get the resized image
resized_image = resize_image(geometry_string)
# Return the resized, crop image
resized_image.crop(Magick::CenterGravity, width, height)
end
def resize_image(geometry_string)
logger.debug "resizing image to #{geometry_string}"
@magick_image.change_geometry(geometry_string) do |w, h, img|
img.resize(w, h)
end
end
def save_medium_image
medium_image = resize_image("275")
medium_image.write(medium_file)
end
def save_large_image
large_image = resize_image("500")
large_image.write(large_file)
end
# Delete images from filesystem
def after_destroy
File.delete(full_file) if File.exist? "#{full_file}"
File.delete(thumbnail_file) if File.exist? "#{thumbnail_file}"
File.delete(rounded_thumbnail_file) if File.exist?
"#{rounded_thumbnail_file}"
File.delete(medium_file) if File.exist? "#{medium_file}"
File.delete(large_file) if File.exist? "#{large_file}"
end
# Returns the filesystem location of the image file
def full_file
"#{FileLocation}/full/#{id}.jpg"
end
def thumbnail_file
"#{FileLocation}/thumbnail/#{id}.jpg"
end
def rounded_thumbnail_file
"#{FileLocation}/rounded_thumbnail/#{id}.jpg"
end
def medium_file
"#{FileLocation}/medium/#{id}.jpg"
end
def large_file
"#{FileLocation}/large/#{id}.jpg"
end
# Returns the location of the image to the browser
def full
"#{DisplayLocation}/full/#{id}.jpg"
end
def thumbnail
"#{DisplayLocation}/thumbnail/#{id}.jpg"
end
def medium
"#{DisplayLocation}/medium/#{id}.jpg"
end
def large
"#{DisplayLocation}/large/#{id}.jpg"
end
def rounded_thumbnail
"#{DisplayLocation}/rounded_thumbnail/#{id}.jpg"
end def resize
if File.exist? full_file
@file = File.open full_file
save
end
end
end
···
On 8/3/05, Joe Van Dyk <joevandyk@gmail.com> wrote:
On 8/3/05, Tim Hunter <cyclists@nc.rr.com> wrote:
> Joe Van Dyk wrote:
>
> > The following Rails/Ruby code gives me this error: "Zero-length blob
> > not permitted".
> >
> > @magick_image = Magick::Image.from_blob(@file.read).first
> >
> > Where @file is a StringIO object or a File object, depending on the
> > size of the uploaded file.
> >
> > @file.read.size returns the expected file size (in bytes).
> >
> > Any ideas?
>
> Well, it works for me. Here's my attempt to reproduce the problem.
>
> require 'RMagick'
> require 'stringio'
>
> file = File.open('Flower_Hat.jpg')
> img = Magick::Image.from_blob(file.read).first
> p img
>
> blob = IO.read('Flower_Hat.jpg')
> sio = StringIO.new(blob)
> img = Magick::Image.from_blob(sio.read).first
> p img
>
>
> The output is:
> tim: ~> ruby test.rb
> JPEG 200x250 DirectClass 8-bit 9kb
> JPEG 200x250 DirectClass 8-bit 9kb
Yeah, I tried to do that test last night and it worked fine.
So I have no idea why the code is failing inside my Image model.