Rails:Carrierwave 重新创建版本不会更改旧图像

发布于 2024-12-01 14:02:21 字数 889 浏览 1 评论 0原文

我的 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 进行存储。

My Rails app uses carrierwave to manage image uploads. I have a watermark version of the images on my site. Previously I was overlaying an image on them, like so:

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

Now I'm overlaying text, like so:

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

Now, this works for new images, but when I call recreate_versions! the old photos are not replaced. How can I get this new watermark to replace the old one?

For what it's worth I'm using Fog with Amazon S3 for storage in both development and production.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清晨说晚安 2024-12-08 14:02:21

这可能不是完全相同的问题,但对于谷歌能力:

我们在文件名中有一个随机哈希,类似于 此讨论线程

重新生成图像时,它会使用新的哈希值生成新图像,但不会更新数据库中存储的文件名,因此它会尝试使用旧名称显示图像。

这重现了问题:

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
}

This might not be quite the same issue, but for googleability:

We have a random hash in the filename similar to what is described in this discussion thread.

When regenerating images, it would generate new images, using a new hash, but it wouldn't update the filename stored in the database, so it would attempt to display images with the old names.

This reproduces the problem:

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"

It gives output like

before: /uploads/foo_123_6a34e47ef5.JPG
after: /uploads/foo_123_d9a346292d.JPG
[#<Image id: 456, foo_id: 123, image: "foo_123_6a34e47ef5.JPG">]

But adding a img.save! after recreating versions fixes it:

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"

With output:

before: /uploads/foo_123_6a34e47ef5.JPG
after: /uploads/foo_123_d9a346292d.JPG
[#<Image id: 456, foo_id: 123, image: "foo_123_d9a346292d.JPG">]

Edit:

Actually, the above worked with files on disk, but not with fog. To make things easy for myself, I ended up just recreating the images and removing the old ones:

Image.all.each { |old|
  new = Image.new(foo_id: old.foo_id, image: old.image)
  new.save!
  old.destroy
}
秋意浓 2024-12-08 14:02:21

您需要在调用 recreate_versions! 之前调用 image.cache_stored_file!

这很奇怪,因为如果文件被缓存,该方法本身会调用该方法,但由于某种原因它不起作用。

You need to call image.cache_stored_file! before calling recreate_versions!

It's weird because the method itself calls that if the file is cached, but for some reason it wasn't working.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文