I have a CarrierWave::Uploader that produces three version of the uploaded image.
# Process files as they are uploaded:
process :resize_to_fit => [400, 400]
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [60, 60]
end
version :small do
process :resize_to_fit => [24, 24]
end
And in my tests I try to verify the dimensions of the generated images
require 'spec_helper'
require 'carrierwave/test/matchers'
describe 'manufacturer logo uploader' do
include CarrierWave::Test::Matchers
before(:each) do
image_path = Rails.root.join('test/fixtures/images', 'avatar100.gif').to_s
#manufacturer = Factory.create(:manufacturer, :page_status => 1)
#manufacturer.logo_image = File.open(image_path)
#manufacturer.save!
end
context "manufacturer logo dimensions" do
it "should have three versions" do
#manufacturer.logo_image.should have_dimensions(400,400)
#manufacturer.logo_image.thumb.should have_dimensions(60,60)
#manufacturer.logo_image.small.should have_dimensions(24,24)
end
end
end
but this test depends on the actual image and resize_to_fit will not necessarily resize it to the specified dimensions. Any ideas on how to test this using stubs?
Here's my solution, which actually processes an image. This is slower than stubs, but verifies the actual resize (as long as the input image is larger than the target size).
describe 'images' do
include CarrierWave::Test::Matchers
before do
MyUploader.enable_processing = true
end
it 'are resized' do
path = Rails.root.join *%w[ spec data sample.png ]
my_model = FactoryGirl.create :my_model, image: path.open
my_model.artwork.small.should be_no_larger_than(300, 400)
end
after do
MyUploader.enable_processing = false
end
end
long shot but can you try to add this
before do
DocumentUploader.enable_processing = true
end
because processing (current version and other versions) could be turned off by default for performance reason
had similar problem related to process set_file_name_to_model that was doing something setting "file_name" on model attribute
http://ruby-on-rails-eq8.blogspot.co.uk/2015/03/carrierwave-uploader-not-triggering.html
Related
I am using Carrierwave version 1.0.0rc to upload and process files to AWS S3 bucket. Here is my environment:
Rails 4.2.0
Ruby 2.1.1
MiniMagick 4.5.1
ImageMagick 6.9.7-0
My uploader determines if the original image to be uploaded is landscape or portrait and will apply processing rules accordingly. The file uploads to the AWS S3 bucket, but then I get the following error:
Errno::ENOENT in SponsorsController#create
No such file or directory # rb_sysopen - uploads/sponsor/logo/30/Breen_Electrical_Logo.jpg
and the extracted source shows this code highlighted:
image = MiniMagick::Image.open(picture.path)
Here is my uploader code:
class LogoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :landscape, if: :is_landscape?
version :portrait, if: :is_portrait?
version :landscape do
process resize_to_fit: [200, 50]
end
version :landscape_sm, from_version: :landscape do
process resize_to_fit: [100, 25]
end
version :portrait do
process resize_to_fit: [50, 200]
end
version :portrait_sm, from_version: :portrait do
process resize_to_fit: [25, 100]
end
private
def is_landscape? picture
image = MiniMagick::Image.open(picture.path)
image[:width] > image[:height]
end
def is_portrait? picture
image = MiniMagick::Image.open(picture.path)
image[:width] < image[:height]
end
end
The private methods seem to opening up the file to compare its width and height values. This worked just fine when I was storing the files in the local public folder. I am guessing that the "picture.path" url is not pointing up to the S3 bucket path to open the file.
Here is my /config/initializers/carrierwave.rb file
require 'fog/aws'
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: <access_key_id>,
aws_secret_access_key: <secret_access_key>,
region: 'us-west-2',
:path_style => true
}
config.fog_directory = <bucketname>
end
I can't seem to find others having the same issue. Any ideas? Thanks in advance.
I think you'll need to refer to the file directly, instead of just the path, since it wouldn't be local. Something like:
ruby
image = MiniMagick::Image.open(picture.file)
I use CarrierWave to generate versions (thumbnails with different sizes) and also to add a watermark on each versions.
I have currently manage to apply the watermark for each thumbnails but I would like to add it on the original image to.
Here is what I tried:
def watermark
manipulate! do |img|
watermark = Magick::Image.read(Rails.root.join('app/assets/images/watermark_512.png')).first
img = img.composite(watermark, Magick::CenterGravity, Magick::OverCompositeOp)
end
end
version :original do
process :watermark
end
version :thumb_512 do
process :resize_to_fit => [512, 512]
process :watermark
end
version :thumb_256 do
process :resize_to_fit => [256, 256]
process :watermark
end
But this does not work. However I tried to simply add
process :watermark
outside any "version" block but all it does is adding twice the watermark on my thumbnails.
You can use store callbacks provided by CarrierWave in your uploader class like this
class SomeUploader < CarrierWave::Uploader::Base
# Your code ...
before :store, :watermark_method
def watermark_method(*args)
# watermark it!
end
end
I'm trying to upload to amazon s3 an existing image on facebook or twitter from an user that has just signed up in my application, but some validation don't let me save the user object, throws: Image is invalid. I thought that was for my extension_white_list but I removed it and it's keeping saying Image is invalid.
This it's not an error, it's just a message from a validation on carrierwave I think, even if the image url string is correct.
AvatarUploader
# encoding: utf-8
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
include CarrierWave::RMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
include CarrierWave::MimeTypes
process :set_content_type
def store_dir
"avatar/#{model.id}"
end
version :thumb do
process resize_to_fill: [50, 50]
end
# def extension_white_list
# %w(jpg jpeg gif png bmp)
# end
end
Creating user:
...
new_user = User.create( :name => auth['info']['name'],
:email => User.email_from_auth(auth) )
auth_image_url = Authentication.larger_image(auth) # a string of user image url from social network authentication data. ie: http://a0.twimg.com/profile_images/1255111511/skyline.jpg
unless auth_image_url.blank?
new_user.remote_image_url = auth_image_url
new_user.save
end
...
Fixed! The error has nothing to do with carrierwave, just the fact that the object does not exist on database in the moment where the image is upload, first I save the new user and then:
after_create :upload_image_from_auth
def upload_image_from_auth
auth = self.authentications.first
unless auth.nil?
self.remote_image_url = auth.larger_image
self.save
end
end
I'm trying to get carrierwave working with S3, and I am getting a signature doesn't match error. The weird thing is that it doesn't look like carrierwave is sending the right secret key. In the error, the post is given as:
"Authorization"=>"AWS AKIAIOLWQKSJFH6E3I5Q:vKgyAw2z4c8zzqGWoxLUbw7I5oI="
Which I assume is supposed to be my publickey:privatekey. The thing is that vKgyAw2z4c8zzqGWoxLUbw7I5oI= is not the private key I have stored in fog.rb. Is that right?
Any help is appreciated.
Request/Response:
request => {:chunk_size=>1048576, :connect_timeout=>60, :headers=>{"Content-Length"=>1557, "Content-Type"=>"image/
gif", "x-amz-acl"=>"public-read", "Date"=>"Wed, 24 Oct 2012 12:45:17 +0000", "Authorization"=>"AWS AKIAIOLWQKSJFH6E3
I5Q:vKgyAw2z4c8zzqGWoxLUbw7I5oI=", "Host"=>"s3.amazonaws.com:443"}, :instrumentor_name=>"excon", :mock=>false, :nonb
lock=>true, :read_timeout=>60, :retry_limit=>4, :ssl_ca_file=>"/home/tim/.rvm/gems/ruby-1.9.3-p194/gems/excon-0.16.5
/data/cacert.pem", :ssl_verify_peer=>true, :write_timeout=>60, :host=>"myeasybnb.s3.amazonaws.com", :host_port=>"s3.
amazonaws.com:443", :path=>"/images%2Fb1bb6639-dc08-4981-9a9b-7175093ac970.gif", :port=>"443", :query=>nil, :scheme=
>"https", :body=>#<File:/home/tim/Dropbox/myeasybnb/tmp/uploads/20121024-0845-20225-1170/240x240.gif>, :expects=>200
, :idempotent=>true, :method=>"PUT"}
response => #<Excon::Response:0xa7a1098 #body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>SignatureD
oesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your
key and signing method.</Message>
fog.rb:
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS', # required
:aws_access_key_id => 'AKIAIOLWQKSJFH6E3I5Q', # required
:aws_secret_access_key => '[my secret key]' # required
}
config.fog_directory = 'myeasybnb' # required
config.fog_public = true # optional, defaults to true
end
Uploader.rb:
# encoding: utf-8
class PhotoUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
# storage :file
storage :fog
# 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
"images"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
class MyUploader < CarrierWave::Uploader::Base
def default_url
asset_path("seeds/" + [version_name, "default.png"].compact.join('_'))
end
end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# Create different versions of your uploaded files:
process :convert => 'jpg'
version :sidecarousel, :if => :is_side_carousel? do
process :resize_to_fit => [2000,1000]
end
version :thumbnail, :if => :is_thumbnail? do
process :resize_to_fill => [240,240]
end
version :linetext, :if => :is_line? do
process :resize_to_fill => [400,200]
end
version :carousel, :if => :is_carousel? do
process :resize_to_fit => [2200, 1000]
end
version :phone do
process :resize_to_fit => [900,900]
end
# def scale(width, height)
# # do something
# end
def is_side_carousel? photo
model.location == 1
end
def is_thumbnail? photo
model.location == 2
end
def is_line? photo
model.location == 3
end
def is_carousel? photo
model.location == 4
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
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
file.nil? ? #filename = nil : #filename = "#{secure_token}.#{file.extension}"
end
def secure_token
var = :"##{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end
def cache_dir
"#{Rails.root}/tmp/uploads"
end
end
I managed to fix this. I'm not exactly sure what I did, but there was a couple issues. (1) I think I was getting the auth error because I was specifying a folder in my uploader. Now, I set my directory in the uploader to "" and specify the folder through the fog configuration.
(2) Another error I was getting was a time mismatch. I run mint in a virtual machine for development, and the time was different from reality. Amazon threw an error at that. Once I set the correct time, that went away.
what I want to do is to save a website url with a full-size snapshot via IMGKit. In one of the views I also want to have a thumbnail version of the snapshot. I'm using carrierwave in order to associate the snapshot with the object an MiniMagick to manipulate it, the problem is that it generates the 'thumbnail' image but doesn't resize it so as a result, I have two full-size snapshots, one of then with 'thumb' as prefix.
I have this model in rails
class Webpage
mount_uploader :snapshot, SnapshotUploader
field :url, type: String
field :title, type: String
after_create :get_snapshot
private
def get_snapshot
file = Tempfile.new(["#{id}#{title}".downcase, '.jpg'], 'tmp', :encoding => 'ascii-8bit')
image = IMGKit.new(url, quality: 90).to_jpg
file.write(image)
file.flush
self.snapshot= file
self.save
file.unlink
end
end
And I have this in the Uploader in order to create the thumbnail version:
class SnapshotUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
version :thumb do
process resize_to_fill: [180, 180]
end
end
Using the console I tried MiniMagick for resizing an image and it works fine son I don't know what is happening.
I'm not sure if I'm doing it right so any help would be appreciated. Thanks.
OK, I'm stupid. I had an initializer with
config.enable_processing = false
so it will never process the image. Just setting it to true or deleting the line solved my problem.