我有一个使用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上的适当位置,跳过调整大小/裁剪。
有人能给我指正确的方向吗?我在网上搜索了一下,似乎什么都找不到,我尝试的一切似乎都不起作用。对原始图片执行.dup
会导致异常,所以这个想法已经过时了。
手动裁剪打破了Paperclip的自动裁剪/调整大小方案。在您想将附件从一个模型复制到另一个模型之前,这是可以的。您有两种选择:将每个样式的裁剪参数保存在数据库中,并在复制后调用"reprocess!"(基于此问题)。
我无意将裁剪数据保存在数据库中,这完全没有用。我决定自己盲目地复制图像,直接调用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