RMagick help

Hi,

So now that I'm not making ridiculous typos, I've got my homegrown
photo uploading system going. But now the question is, how do I
implement ImageMagick photo features? I've got ImageMagick and the
RMagick gem installed, but I'm not sure at what point in the process I
should implement the methods RMagick exposes?

To recap the basic file uploading code:

I have a model picture that has the following methods:
  validates_format_of :content_type,
  :with=>/^image/,
  :message=>'Uploading is limited to pictures'

  def uploaded_picture=(picture_field)
    self.name = base_part_of(picture_field.original_filename)
    self.content_type = picture_field.content_type.chomp
    self.data = picture_field.read
  end

  def base_part_of(file_name)
    File.basename(file_name).gsub(/[^\w._-]/,'')
  end

Basic validation to make sure it is an image, an accessor? method to
instruct it to read the data being uploaded and a method to write the
filename.

Turns out when you type it correctly, the controller isn't that tough
either:

  def get
    @picture =Picture.new
  end

  def picture
    @picture=Picture.find(params[:id])
    send_data(@picture.data,
              :filename=>@picture.name,
              :type=>@picture.content_type,
              :disposition=>"inline")
  end

  def save
    @picture=Picture.new(params[:picture])

    if @picture.save
      redirect_to(:action=>'show', :id=> @picture.id)
    else
      render(:action=> :get)
    end
  end

  def show
    @picture=Picture.find(params[:id])
  end

There are 3 views (index, show, get) but I'm omitting them.

If I've understood correctly, I need to create an Rmagick object so I
can get at RMagick's methods. Judging from the docs, I think I would
type:

picture_converted= Magick::Image.read(?)
picture_converted.change_geometry!('320x240') { |cols, rows, img|
img.resize!(cols, rows)
}

I've put a question mark as the argument for read because I'm not sure
what object I can tap into to manipulate it. Is it as simple as using
ActiveRecord to retrieve a particular image and loading that into
picture_converted?

picture_loaded=Picture.find(params[:id])
picture_converted=Magick::Image.read(picture_loaded)

I really appreciate the help...if any of you are in Palo Alto, I owe
you a beer or something!

If I've understood correctly, I need to create an Rmagick object so I
can get at RMagick's methods. Judging from the docs, I think I would
type:

picture_converted= Magick::Image.read(?)
picture_converted.change_geometry!('320x240') { |cols, rows, img|
img.resize!(cols, rows)
}

Magick::Image.read requires a file object, so you're out of luck
there. from_blob takes a blob (ie a string)

Fred

Hi Fred,

Is @picture not a file object? If @picture is saved at some point and
given a filename, I imagine that there's some point along the way that
it becomes a file object, no?

Ron

Hi Ron,

Ive written some stuff using ImageMagick.
I don't have the time right now to explain everything.
But if you want, I can send you some code samples
at the email in your profile.
It covers the whole upload thing and using RMagick/ImageMagick
for creating some previews, thumbnails and stuff like that.

Hi Fred,

Is @picture not a file object? If @picture is saved at some point and
given a filename, I imagine that there's some point along the way that
it becomes a file object, no?

As you've shown it, @picture is an ActiveRecord object and the image
data is stored in the database. No file object in sight.

Fred

Ron

Hi Fred,

Yea, I realized that shortly after hitting the post button...should be
less quick off the mark. Hmm...looks like I'm going to have to
rewrite the file upload feature to right a file and store the filename
in the database.

Hi Fred,

Yea, I realized that shortly after hitting the post button...should be
less quick off the mark. Hmm...looks like I'm going to have to
rewrite the file upload feature to right a file and store the filename
in the database.

Not necessarily, like I said Image.from_blob should sort you out. You
might want to check out attachment_fu as it does a lot of this sort of
stuff.

Fred

Hi Ron,

Ive written some stuff using ImageMagick.
I don't have the time right now to explain everything.
But if you want, I can send you some code samples
at the email in your profile.
It covers the whole upload thing and using RMagick/ImageMagick
for creating some previews, thumbnails and stuff like that.

right, here it is:
http://pastie.org/215434

Hi Fred and Thorsten,

Thanks so much for the help.

I don't quite understand from_blob...? What does it do?

Thorsten: thanks for the code! I really appreciate it. I'll try
attachment_fu at some point--I'm writing this myself just so that I
understand how it works. If I use attachment_fu later on, I want to
make sure I understand how it does this stuff...

R

Hi Fred and Thorsten,

Thanks so much for the help.

I don't quite understand from_blob...? What does it do?

From the rmagick doc:

Image.from_blob(aString) [ { optional arguments } ] -> anArray

Description
Creates an array of images from a BLOB, that is, a Binary Large
OBject. In RMagick, a BLOB is a string.

Arguments
A blob can be a string containing an image file such as a JPEG or GIF

Fred

Ah got it...I'm still not sure where I would put it. I'm not sure if
I could put something like this in the controller:

  def resize
    @picture=Picture.find(params[:id])
    Image.from_blob(@picture.data)
    Image.change_geometry!('320x240') { |cols, rows, img|
    Image.resize!(cols, rows)
  end
?

Ah got it...I'm still not sure where I would put it. I'm not sure if
I could put something like this in the controller:

def resize
   @picture=Picture.find(params[:id])
   Image.from_blob(@picture.data)
   Image.change_geometry!('320x240') { |cols, rows, img|
   Image.resize!(cols, rows)
end

You could put that absolutely anywhere in your app, as long as
params[:id] was defined.

Fred

Hmm..this is getting a bit discouraging. At the moment, I'm getting a
no method error for change_geometry!, which is strange.

I'm wondering how to dump the BLOB data into some kind of object that
RMagick can then operate on? I tried
Image=Magick::ImageList.new
Then proceeded to use change_geometry!, but then I got the undefined
constant error.

How can I create an object that exposes the RMagick methods from the
blob data?

R

Oops I figured it out...the thing to do is to create an instance
variable to hold it. I was just creating a local variable, which must
not work because of the structure of Rails.

My save code now looks like:
    @picture=Picture.new(params[:picture])

      @image=Magick::ImageList.new
      @image.from_blob(@picture.data)
      @image.change_geometry!('320x240') {|cols, rows, img|
      @image.resize!(cols, rows)}
      @picture.data=@image.to_blob
      if @picture.save
      redirect_to(:action=>'show', :id=> @picture.id)
    else
      render(:action=> :get)
    end

Thorsten, thanks for the pastie -- I've been messing with RMagick with
various levels of success and your pastie may get me back on track.

Ron, I'm working on this sort of stuff for my personal photography web
site, so perhaps some collaboration is in order? Right now I'm stuck
on deadline for a video project to be shown next Saturday, so I can't
go full barrel on this. But...

My general flow is this:

Export photos from Aperture into JPEGs generally fitting within
1024x1024 and watermarked, putting into a new folder, whose name is
the "event" I want these photos referenced in in my database,
appropriate for event index and viewing.

Then in my Rails app, admin controller, I want to point to the folder
and let 'er rip:
1) Add the filenames to my database
2) Create thumbnails and store them in public/images/thumbnails/

Then in my list/show/etc views I can build nice photo display pages of
the images for any given event.

Thoughts? Parallel tracks?

Cheers,

Jim

Hey Jim,

That's certainly an interesting line of thought...we definitely should
chat. I'm building a database for my boss. Basically, there's all
this text in a MySQL database that has to live with multiple
photographs. So I need to be able to upload the file and then
generate a thumbnail.

Little short on time over the next couple of days, too....but I'd
certainly be interested in collaborating a bit, since it sounds like
we're trying to do similar things.

More later...

Ron