Rails:使用回形针、S3和RMagick进行图像裁剪

时间:2021-01-25 21:23:16

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):

我目前正在尝试编写一个自定义的图像裁剪系统,类似于互联网上的其他系统,用户可以选择裁剪区域,然后相应地裁剪图像。应用程序在Rails中,我们使用Paperclip和Amazon S3存储文件。我遇到了很多麻烦,不过要让RMagick适当地从S3中裁剪文件。这是当前的代码(不工作):

   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.

主要问题是裁剪后的图像没有通过paperclip上传至S3,因此没有正确的裁剪。有人用曲别针做过类似的尝试吗?这可能是不可能的,但任何帮助都将非常感谢。

3 个解决方案

#1


5  

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.

编辑:只是一个简短的说明,Tempfile是paperclip库的一部分。

#2


0  

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 ..

您可以在模型上定义一些attr_accessors,并在创建实际文件之前在controller操作中设置它们。下面这个应该可以。

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

#3


0  

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.

实际上,我在自己的代码中有同样的问题,并且在我的todo列表中有这个问题。

#1


5  

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.

编辑:只是一个简短的说明,Tempfile是paperclip库的一部分。

#2


0  

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 ..

您可以在模型上定义一些attr_accessors,并在创建实际文件之前在controller操作中设置它们。下面这个应该可以。

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

#3


0  

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.

实际上,我在自己的代码中有同样的问题,并且在我的todo列表中有这个问题。