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