Question

I'm currently trying to code a custom image cropping system similar to other ones on the internet where a user can select a cropping area and then have their image cropped accordingly. The application is in Rails and we're using Paperclip with Amazon S3 to store the files. I'm having a lot of trouble though getting RMagick to appropriately crop the file from S3. Here is the current code (which does not work):

   if params[:width].to_i > 0 and params[:height].to_i > 0 then
      photo = Photo.find(params[:id])
      image_data = Net::HTTP.get_response(URI.parse(photo.photo.url(:big))).body
      orig_img = Magick::ImageList.new
      orig_img.from_blob(image_data)

      args = [params[:x1].to_i, params[:y1].to_i, params[:width].to_i, params[:height].to_i]
      orig_img.crop!(*args)
      photo.update_attributes({:photo => orig_img.to_blob})

      photo.photo.reprocess!
      photo.save
    end

The main problem is that the cropped image is not uploaded back to S3 through paperclip, and thus not properly cropped. Has anyone attempted something like this with paperclip before? This may not even possible, but any help would be greatly appreciated.

Was it helpful?

Solution

I've been able to solve this problem for the time being as follows:

  photo = Photo.find(params[:id])
  image_data = Net::HTTP.get_response(URI.parse(photo.photo.url(:big))).body
  orig_img = Magick::ImageList.new
  orig_img.from_blob(image_data)

  args = [params[:x1].to_i, params[:y1].to_i, params[:width].to_i, params[:height].to_i]
  orig_img.crop!(*args)

  tmp_img = Tempfile.new("image_data")
  orig_img.format = "png"
  tmp_img.write(orig_img.to_blob)
  photo.photo = tmp_img
  tmp_img.close

  photo.photo.reprocess!
  photo.save

The main concern here is the speed hit of creating a new temporary file, so probably we will have to create our own custom interface. Hopefully this can be a good starting point for people solving a similar issue.

EDIT: Just a quick note, Tempfile is part of the paperclip libraries.

OTHER TIPS

You could define some attr_accessors on the model and set them in the controller action before creating the actual file. The below should work ..

class Poodle < ActiveRecord::Base
  has_attached_file :avatar, :styles => Proc.new{|a| a.instance.get_styles}
  attr_accessor :width, :height


  def get_styles(style = "medium")
    return {style.to_sym => [self.width, self.height].join("x") + ">" }
  end
 end

You may want to take a closer look at Paperclip processors.

I actually have the same problem in my own code, and have that on my todo list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top