Reputation: 2420
This is another question in pursuit of an answer to this question.
In my watermark processor if I set the watermark image's path to a static watermark image, everything works just fine.
I have three models: Watermark, Gallery, and Photo. Watermark has_many :galleries
. Gallery belongs_to :watermark
and has_many :photos
. Photo belongs_to :gallery
and mount_uploader :image, PhotoUploader
.
Here's what I'd like to do in photo_uploader.rb:
version :large do
process :watermark
process :resize_to_limit => [600, 600]
end
def watermark
manipulate! do |img|
watermark = Magick::Image.read(model.gallery.watermark.image_url).first
img = img.composite(watermark, Magick::CenterGravity, Magick::OverCompositeOp)
end
end
While using model methods/attributes works fine in the store_dir method, it doesn't work in the watermark processor. How can I pass the model.gallery.watermark.image_url argument to the watermark processor?
Upvotes: 3
Views: 1924
Reputation: 11
the problem is the that by the time the image is mounted on the Model, the variables inside the watemark def, inside the uploader class, are not avialiabled. Thats what did. I'm using mongoid to deal with mongoDB. I set a param inside the Model, that will hold the value that i want eg. the value the_current_model.gallery.watermark.image_url. This param will be user_image.
class Asset
include Mongoid::Document
mount_uploader :image, AssetUploader
field :user_image
attr_accessible :user_image
after_save :mark_it
private
def mark_it
image.recreate_versions! if user_image.present?
end
end
The key to solve this problem is recreate the image (as you see on the model calling the mark_it def) after the data being saved on the database and the param user_image allowed to be used for you uploader class.
class AssetUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
# storage :fog
after :cache, :unlink_original_cache
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
process :resize_to_fit => [800, 800]
process :quality => 80
version :thumb do
process :resize_to_fit => [200, 200]
end
version :large do
process :watermark
end
def watermark
if model.user_name.present?
manipulate! do |img|
text = Magick::Draw.new
text.gravity = Magick::CenterGravity
text.fill = 'white'
text.pointsize = 40
text.stroke = 'none'
text.annotate(img, 0, 0, 0, 0, "#{model.user_name}")
img
end
end
end
def unlink_original(file)
File.delete path if version_name.blank?
end
def unlink_original_cache(file)
File.delete if version_name.blank?
end
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
Now the key is here:
def watermark
if model.user_name.present?
manipulate! do |img|
text = Magick::Draw.new
text.gravity = Magick::CenterGravity
text.fill = 'white'
text.pointsize = 40
text.stroke = 'none'
text.annotate(img, 0, 0, 0, 0, "#{model.user_name}")
img
end
end
end
The method watermark only creates the image with the watermark on it, if the user_name param on the model is set (created on the db). So when the data is saved on the db, this param is avaliabled for you uploader class to use as want.
Thats what I did, and it worked very well! I hope it could help!
Upvotes: 1