【问题标题】:Rails: Carrierwave recreate versions does not change old imagesRails:Carrierwave 重新创建版本不会更改旧图像
【发布时间】:2011-08-25 18:51:48
【问题描述】:

我的 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 一起用于开发和生产中的存储。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 amazon-s3 rmagick carrierwave


    【解决方案1】:

    这可能不是完全相同的问题,但对于 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
    }
    

    【讨论】:

    • 这确实正确识别了我遇到的问题。我最终想出了一个稍微不同的解决方案,但这很有效。
    • 感谢您的建议,我遇到了类似的问题。我的问题的解决方法是确保生成的新文件具有不同的唯一名称。
    • 不得不再次执行此操作,使用 Fog (S3) 重新生成整个图像(包括所有版本):record.remote_image_url = record.image_url; i.save!
    【解决方案2】:

    您需要先拨打image.cache_stored_file!,然后再拨打recreate_versions!

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2015-08-02
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多