My Rails应用使用carrierwave管理图片上传。我的网站上有图像的水印版本。以前我在它们上面覆盖了一个图像,如下所示:
def watermark
manipulate! do |img|
logo = Magick::Image.read("#{Rails.root}/public/images/plc-watermark.png").first
img = img.composite(logo, Magick::SouthEastGravity, Magick::OverCompositeOp)
end
end
现在我正在覆盖文字,如下:
def watermark
manipulate! do |img|
text = Magick::Draw.new
text.gravity = Magick::CenterGravity
text.pointsize = 12
text.font = "#{Rails.root}/public/fonts/hn300.ttf"
text.stroke = 'none'
text.annotate(img, 0, 0, 0, 0, "Photo © #{model.user.full_name}\nHosted by Placeology.ws\nPlease log in to remove this watermark")
img
end
end
现在,这适用于新图像,但是当我调用recreate_versions时!旧照片不会被替换。如何才能获得这个新水印来取代旧水印?
为了我的价值,我在开发和生产中使用Fog和Amazon S3进行存储。
答案 0 :(得分:8)
这可能不是完全相同的问题,但对于googleability:
我们在文件名中有一个类似于this discussion thread中描述的随机哈希。
重新生成图像时,它会使用新的哈希生成新图像,但不会更新存储在数据库中的文件名,因此会尝试显示旧图像的图像。
这再现了问题:
bundle exec rails runner "Foo.find(123).images.each { |img| uploader = img.image; puts %{before: #{img.image.inspect}}; uploader.recreate_versions!; puts %{after: #{img.reload.image.inspect}} }; p Foo.find(123).images"
它提供类似
的输出before: /uploads/foo_123_6a34e47ef5.JPG
after: /uploads/foo_123_d9a346292d.JPG
[#<Image id: 456, foo_id: 123, image: "foo_123_6a34e47ef5.JPG">]
但是在重新创建版本后添加img.save!
会修复它:
bundle exec rails runner "Foo.find(123).images.each { |img| uploader = img.image; puts %{before: #{img.image.inspect}}; uploader.recreate_versions!; img.save!; puts %{after: #{img.reload.image.inspect}} }; p Foo.find(123).images"
输出:
before: /uploads/foo_123_6a34e47ef5.JPG
after: /uploads/foo_123_d9a346292d.JPG
[#<Image id: 456, foo_id: 123, image: "foo_123_d9a346292d.JPG">]
修改强>
实际上,上面的内容适用于磁盘上的文件,但不适用于雾。为了让自己变得简单,我最终只是重新创建了图像并删除了旧图像:
Image.all.each { |old|
new = Image.new(foo_id: old.foo_id, image: old.image)
new.save!
old.destroy
}
答案 1 :(得分:4)
您需要在致电image.cache_stored_file!
recreate_versions!
这很奇怪,因为该方法本身会调用该文件,如果该文件被缓存,但由于某种原因它无法正常工作。