3

我有一个使用 Paperclip 处理图像的模型。当图像上传时,会为一些 javascript 裁剪进行预览,然后根据所选裁剪制作缩略图和预览尺寸。在 S3 上总共给我们 3 张图像:

  • 原始图像
  • 预览(来自用户选择的裁剪)
  • 拇指(来自用户选择的裁剪)

附件模型中的代码是:

has_attached_file :picture, ASSET_INFO.merge(
  :whiny => false,
  :styles       => { :thumb => '200>x200#', :preview => '400x300>' },
  :processors   => [:jcropper],
  :preserve_files => true
)

我们有一些功能允许用户为自己的目的制作对象的副本,并且我们想要复制图像。我以为只是做一个简单的

new_my_model.picture = original_my_model.picture if original_my_model.picture_file_name #no file name means no picture

会完成工作,它确实,但只是一种。

它正在复制图片,然后根据模型中设置的内容重新处理预览和缩略图。

我想做的是将所有 3 个现有图像(原始图像、拇指图像和预览图像)复制到新对象,因为它们是原始图像,然后将它们保存在 S3 上的适当位置,跳过调整大小/裁剪。

谁能指出我正确的方向?我在网上搜索过,似乎找不到任何东西,而且我尝试的一切似乎都不起作用。对原始图片执行 a.dup会导致异常,因此该想法已失效。

4

1 回答 1

3

手动裁剪会破坏 Paperclip 的自动裁剪/调整大小方案。这没关系,直到您想将附件从一个模型复制到另一个模型。您有两个选择:将每种样式的裁剪参数保存在数据库中,然后调用“重新处理!” 复制后(基于this question)

我无意将裁剪数据保存在数据库中,这完全没用。我决定自己盲目复制图片,直接调用S3。不是最佳的,但有效:

module Customizable

  def duplicate copy_args
    new_model = self.dup
    copy_args.each {|key, val| new_model[key] = val}
    new_model.save

    s3 = AWS::S3.new(self.image.s3_credentials)
    bucket = s3.buckets[self.image.s3_credentials[:bucket]]

    styles = self.image.styles.keys.insert(0, :original)

    begin
      styles.each do |style|
        current_url = self.image.path(style)
        current_object = bucket.objects[current_url]
        if current_object.exists?
          # actually asking S3 if object exists
          new_url = new_model.image.path(style)
          new_object = bucket.objects.create(new_url)
          # this is where the copying takes place:
          new_object.copy_from(current_object)
          new_object.acl = current_object.acl
        end
      end
    rescue Exception => err
      return err
    end

    return true
  end

end

在我的模型中:

class Product < ActiveRecord::Base

  # ...
  has_attached_file :image, ...
  # ...
  include Customizable

  def customize product_id
    return self.duplicate({:in_sale => false}) #resetting some values to the duplicated model
  end

  # ...
end
于 2014-06-18T22:53:52.543 回答