Reputation: 43103
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.
Upvotes: 5
Views: 6637
Reputation: 16274
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
}
Upvotes: 9
Reputation: 506
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.
Upvotes: 5