Rectangle 27 14

Finally got this! After trying a bunch of different custom image manipulation functions and manual cropping it's actually as simple as I had hoped for...

process :resize_to_fill => [400, 400]

Crops it into a 400x400 square from the direct center of the original image.

Be sure to add/uncomment the include CarrierWave::RMagick in your uploader for this to work.

ruby on rails - CarrierWave + RMagick Square Crop? - Stack Overflow

ruby-on-rails ruby image-processing carrierwave rmagick
Rectangle 27 31

Depending on the setup. As Senthil writes, as long as you have a cache-proxy in front, it's fine with Dragonfly.

But if you are using the built-in rails caching, Carrierwave will perform better, as the files can be loaded without any processing. If you don't do any processing, it doesn't matter.

Here's how I summarized when considering both for Images on a project with Mongomapper:

  • Can use files directly from a static/cached document
  • Uses storagespace for every file/thumb generated. If you use normal file storage, you might run out of inodes!
  • Should work with mongomapper, as it only extends ActiveModel
  • Generates thumbs on the fly (easier to create new layouts/thumbsizes)
  • Eats CPU on every request if you don't have a cache-proxy, rack::cache or similar.
  • No way to access thumbs as files if needed.

A future wish is for carrierwave to suppert MongoMapper again. After using both in various situations, I've found that the features in MongoMapper (rails3 branch) always works, and are easy to extend using plugins. Cannot say the same for Mongoid as of now, but that might change.

You should be able to store thumbs if you really want. You can make a separate image store. Stick with Mongoid ;)

"Every once in a while MongoMapper changes something about the library and it ends in me sitting for ours poring over their non-existant documentation (i.e. the source code) trying to figure out what the hell is wrong. I've had enough of this." groups.google.com/group/carrierwave/browse_thread/thread/ That's by the author of carrierwave, looks like carrierwave-mongomapper support won't be happening anytime.

Dragonfly can actually create thumbnails on-upload too if needed - see markevans.github.com/dragonfly/ - also you can access thumbs as files using the methods 'to_file' or 'file' markevans.github.com/dragonfly/

Thanks for the info Mark :) Now it's dead simple to have mixed on-the-fly + on-upload :)

ruby on rails - Carrierwave or Dragonfly - Stack Overflow

ruby-on-rails ruby file-upload rubygems dragonfly-gem
Rectangle 27 64

# config/deploy.rb
set :shared_children, shared_children + %w{public/uploads}
:shared_children
%w(public/system log tmp/pids)

Don't forget to run cap deploy:setup after changing :shared_children so that the new targets are created under shared.

Capistrano 3 uses the linked_dirs setting and doesn't specify public/system as a default anymore.

set :linked_dirs, fetch(:linked_dirs) + %w{public/system public/uploads}

It did created the uploads folder inside shared, but the files aren't save there. am I missing a step?

Could be that the symlinks haven't been created. Run cap deploy again and check that releases/current/public/uploads is a symlink to shared/uploads. Also, make sure you're not using a really ancient version of Capistrano.

I think that your solution looks great but really I didn't try that way, so for the amount of UP votes, I will give you the "accept". Thanks

I am using capistrano 3. I only added this line to deploy.rb set :linked_dirs, %w{public/uploads}. Got an error when using the fetch(:linked_dirs) part.

ruby on rails - Carrierwave files with Capistrano - Stack Overflow

ruby-on-rails ruby-on-rails-3 capistrano carrierwave
Rectangle 27 26

In the railscast, Ryan's solution was to convert the coords to work with the original image by finding the ratio between the large version and the original version. I was able to get it to work with Carrierwave and jCrop by following the same logic. Interesting enough Carrierwave does not store the dimensions of the images. I was able to hack together something from this post: http://code.dblock.org/ShowPost.aspx?Id=194.

class User < ActiveRecord::Base

  attr_accessor :password, :crop_x, :crop_y, :crop_h, :crop_w
  after_update :reprocess_profile, :if => :cropping?

  mount_uploader :profile, ProfileUploader

  def cropping?
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
  end

  def profile_geometry
    img = Magick::Image::read(self.profile.current_path).first
    @geometry = {:width => img.columns, :height => img.rows }
  end

  private

  def reprocess_profile
    self.profile.recreate_versions!
  end

end
class AccountController < ApplicationController

  def crop
    @account = current_user
  end

  def crop_update
    @account = current_user
    @account.crop_x = params[:account]["crop_x"]
    @account.crop_y = params[:account]["crop_y"]
    @account.crop_h = params[:account]["crop_h"]
    @account.crop_w = params[:account]["crop_w"]
    @account.save
    redirect_to account_path
  end

end
class ProfileUploader < CarrierWave::Uploader::Base

  def extension_white_list
    %w(jpg jpeg gif png)
  end

  version :large do
    process :resize_to_fit => [500, 500]
  end

  version :thumb do
    process :manualcrop
    process :resize_to_fill => [100, 100]
  end

  def manualcrop
    return unless model.cropping?
    manipulate! do |img| 
      img = img.crop(model.crop_x.to_i,model.crop_y.to_i,model.crop_h.to_i,model.crop_w.to_i) 
    end 
  end

end
<% content_for :head do %>
<%= stylesheet_link_tag "jquery.Jcrop" %>
<%= javascript_include_tag "jquery.Jcrop.min" %>
<script type="text/javascript" charset="utf-8">
$(function() {
  $('#cropbox').Jcrop({
    onChange: update_crop,
    onSelect: update_crop,
    setSelect: [0, 0, 500, 500],
    aspectRatio: 1
  });
});

function update_crop(coords) {
    var rx = 100/coords.w;
    var ry = 100/coords.h;
    var lw = $('#cropbox').width();
    var lh = $('#cropbox').height();
    var ratio = <%= @account.profile_geometry[:width] %> / lw ;

  $('#preview').css({
    width: Math.round(rx * lw) + 'px',
    height: Math.round(ry * lh) + 'px',
    marginLeft: '-' + Math.round(rx * coords.x) + 'px',
    marginTop: '-' + Math.round(ry * coords.y) + 'px'
  });
  $("#crop_x").val(Math.round(coords.x * ratio));
  $("#crop_y").val(Math.round(coords.y * ratio));
  $("#crop_w").val(Math.round(coords.w * ratio));
  $("#crop_h").val(Math.round(coords.h * ratio));
}
</script>
<% end %>

<%= image_tag @account.profile_url(:large), :id => "cropbox" %>

<h3>Preview</h3>
<div class="preview">
    <%= image_tag @account.profile_url(:large), :id => "preview" %>
</div>

<%= form_for @account, :as => :account, :url => { :action => "crop_update" } do |f| %>
    <% for attribute in [:crop_x, :crop_y, :crop_h, :crop_w] %>
        <%= f.hidden_field attribute, :id => attribute %>
    <% end %>
    <p><%= f.submit "Crop" %></p>
<% end %>
.preview {
    width:100px;
    height:100px;
    overflow:hidden;
}

This is fantastic, thanks so much! One small problem, though...in your manualcrop method (inside "profile_uploader.rb") you reversed the order of the last two parameters for crop. According to RMagick documention it should be img.crop(x, y, width, height).

ruby on rails - Carrierwave crop specific version - Stack Overflow

ruby-on-rails ruby imagemagick rmagick carrierwave
Rectangle 27 29

Determine file extension (I suppose a name for mounted uploader is 'file'):

file = my_model.file.url
extension = my_model.file.file.extension.downcase
disposition = 'attachment'
mime = MIME::Types.type_for(file).first.content_type

if %w{jpg png jpg gif bmp}.include?(extension) or extension == "pdf"
  disposition = 'inline'
end

And then send the file:

send_file file, :type => mime, :disposition => disposition

Thank you very much, i like the style of your solution, and it worked perfectly. Again, thanks for the reply!!

where exactly in the rails project files you place the disposition and MIME type vars?

ruby on rails - Carrierwave how to get the file extension - Stack Over...

ruby-on-rails ruby ruby-on-rails-3 file-upload carrierwave
Rectangle 27 23

You've set config.fog_public to false and are using Amazon S3 for storage. URLs for private files through S3 are temporary (they're signed and have an expiry). Specifically, the URL posted in your question has an Expires=1354859553 parameter.

1354859553 is Fri, 07 Dec 2012 05:52:33 GMT, which is in the past from the current time, so the link has effectively expired, which is why you're getting the Access Denied error.

You can adjust the expiry out further (the default is 600 seconds) by setting

config.fog_authenticated_url_expiration = ... # some integer here

If you want non-expiring links either

config.fog_public
true
  • have your application act as a middle man, serving the files up through send_file. Here is at least one question on SO covering this

hi, this sounds correct! I must have something buggering it up lol!, Ill post update

haha, my dev and production have diffirent db's so images where not showing on local, pulled prod db and now it seems to work pretty nicely. TX!

If I change fog_public from false to true when I have images uploaded and live on my app, how do I get the images working correctly? Reprocess them?

You need to change the ACL on those objects to allow 'everyone' view permissions. One way is to write a small script (or even a rake task through your Rails app) to iterate the objects in the bucket, marking each to be public. Check out acl= in the fog gem. You would just set this to "public-read" for each file and call save. There may be a simpler way directly through the AWS panel, but you can see how simple it is with this gem.

ruby on rails - Carrierwave fog Amazon S3 images not displaying - Stac...

ruby-on-rails ruby amazon-s3 carrierwave fog
Rectangle 27 10

Dragonfly does processing on the fly, i.e.

is meant to be used behind a cache-proxy such as Varnish, Squid or Rack::Cache, so that while the first request may take some time, subsequent requests should be super-quick!

ruby on rails - Carrierwave or Dragonfly - Stack Overflow

ruby-on-rails ruby file-upload rubygems dragonfly-gem
Rectangle 27 7

I think you might want to recreate versions since you might have create thumb size for some images after you uploaded some other files.

image.avatar.url(:thumb)

above syntax is fine

image.avatar.recreate_versions!

on all avatars you might be missing.

image.avatar.image_url(:thumb)

ruby on rails - carrierwave thumb issue - Stack Overflow

ruby-on-rails imagemagick carrierwave rmagick
Rectangle 27 28

At some point, I don't know where, I added a fog.rb file with my CarrierWave configuration to the lib/carrierwave/storage directory. I got desperate, paid for a Railscasts subscription so I could watch episode #383 (http://railscasts.com/episodes/383-uploading-to-amazon-s3?autoplay=true) and at 3:02 I found the error of my ways. The Carrierwave configuration needed to be placed in config/initializers/carrierwave.rb.

I don't know where I got this other location but once I moved the config to the proper location, everything is good.

You're not an idiot. I did the same thing! It's because of the ambiguous phrasing in the carrierwave readme (search for lib/carrierwave/storage).

Another idiot of the same kind here =p

I did the same thing. Carrierwave documentation lists lib/carrierwave/storage/fog.rb and doesn't specify the path you provided.

ruby on rails - Carrierwave / Fog / S3 "is not a recognized storage pr...

ruby-on-rails amazon-s3 carrierwave
Rectangle 27 19

You can do something like this in your uploader file, and it will also work for versioned files (i.e. if you have one image and then create 3 other thumbnail versions of the same file, they will all have the same name, just with size info appended onto the name):

# Set the filename for versioned files
  def filename
    random_token = Digest::SHA2.hexdigest("#{Time.now.utc}--#{model.id.to_s}").first(20)
    ivar = "@#{mounted_as}_secure_token"    
    token = model.instance_variable_get(ivar)
    token ||= model.instance_variable_set(ivar, random_token)
    "#{model.id}_#{token}.jpg" if original_filename
  end

This will create a filename like this for example: 76_a9snx8b81js8kx81kx92.jpg where 76 is the model's id and the other bit is a random SHA hex.

WOAH. You just made my week! This works flawlessly. I modified what you had a tiny bit to just make it be a timestamp using the format I was using already (because it pleases me aesthetically). But this does EXACTLY what I needed and in a very easy to understand and elegant Ruby sort of way in a place that makes sense. This really really REALLY should be in the Carrierwave readme. I cannot be the only person using this otherwise fantastic gem who has nearly pulled out their hair trying to figure this seemingly trivial task out.

This code will break though, because filename can't use model.id, since it isn't set until the resource is created.

I have been burnt by using model.id in filenames. Do not use it. See groups.google.com/forum/#!topic/carrierwave/5yiZmAPfMPk I believe the carrierwave generator does include an advice now to avoid model.id or version.name

ruby on rails - CarrierWave: Create the same, unique filename for all ...

ruby-on-rails ruby ruby-on-rails-3 filenames carrierwave
Rectangle 27 7

require 'carrierwave/processing/mime_types'
include CarrierWave::MimeTypes
process :set_content_type

I've tried this, but still get the same result of "binary/octet-stream". I've even tried pull directly from the master branch on github.

ruby on rails - Carrierwave Setting Content-Type to Octet-Stream - Sta...

ruby-on-rails ruby-on-rails-3 amazon-s3 carrierwave
Rectangle 27 4

image.avatar.thumb.url
# or
image.avatar.url(:thumb)

Thanks, just tried both. The first version gives the error "undefined method `thumb' for /uploads/IMG_0185.jpg:AvatarUploader". The second version gives the error "Version thumb doesn't exist!" Any other suggestions? Appreciate the help.

Also you have another end at the end of your AvatarUpload class, I assume, that just got cut off?

Yeah, still have the end at the bottom of the class. Add the public, but still getting the same errors. Just confused on why it wouldn't recognize thumb as a method when it's clearly there.

I have an almost identical setup, hmmm... could we see the model where its set up?

ruby on rails - carrierwave thumb issue - Stack Overflow

ruby-on-rails imagemagick carrierwave rmagick
Rectangle 27 11

I realized this has to do with the new AWS Identity and Access Management (IAM). I had created a new IAM user, but I hadn't given that user the correct privileges. In the past, there was only one user, and that user had admin privileges. Now you have to create a user, give that user the correct privileges, and use that user's credentials. I hope this helps someone.

Yeah, when you introduce IAM it does make things more complicated (especially compared to the admin-everything default credentials). Glad you were able to figure this out.

I had the same problem and looked everywhere for a solution! Thanks for sharing

Thanks very much for this. I been struggling with this for a while, and this comment saved me.

ruby on rails - CarrierWave Fog Credentials, Access Denied - Stack Ove...

ruby-on-rails amazon-web-services amazon-s3 carrierwave fog
Rectangle 27 10

When you first create a user it gets no 'user policies' under 'permissions.' Once I attached a user policy things worked.

You a true bro! Helping out and saving the day.

I know this is old but your answer rescued me after hours of fighting permission errors. To provide even more detail for future lost souls... the policy that fixed it for me was called "AmazonS3FullAccess". Thanks!

ruby on rails - CarrierWave Fog Credentials, Access Denied - Stack Ove...

ruby-on-rails amazon-web-services amazon-s3 carrierwave fog
Rectangle 27 7

bundle exec sidekiq -q carrierwave,5 default

Same here, saved me hours of frustation

ruby on rails - Carrierwave backgrounder sidekiq no workers - Stack Ov...

ruby-on-rails carrierwave sidekiq
Rectangle 27 1

def create_from_uploader
    p_attr = params[:photo]
    p_attr[:photo] = p_attr[:photo][0] if p_attr[:photo].is_a?(Array)
    @photo = @user.photos.build(p_attr)
    if @photo.save
      flash[:notice] = "Succes"
    end
  end

And in your haml view html options for form like this - html: {multipart: true}, and for file_field use multiple: true

That doesn't seem to be the problem. I was able to localize problem to custom written validation method that validates dimensions. This method is executed once pastebin.com/730wMrFM Problem is that when i set multiple => true, file variable is blank Why's that?

jquery - Ruby on Rails - Carrierwave, Can't upload multiple images - S...

jquery ruby-on-rails ruby image carrierwave
Rectangle 27 8

First make sure you use the right credentials by not setting custom region and custom directory (create a fake bucket for free in the default region)

Then I think you are not using the right name for the region. Try setting your region like this:

:region  => 'ap-southeast-1'

Thank you! I did what you asked me to (check regions, did default bucket, etc) and somehow it worked! Also, in case anyone somehow faces the same problem: make sure to restart your development app server everytime you changed something in fog.rb! Newbie mistake, I know. :)

S3 does not require region selection.

It might have changed but a while ago S3 had a standard endpoint that redirected you to the proper region for a given bucket. So this was not ideal because each request was redirected

ruby on rails - Carrierwave uploading with s3 and fog - Stack Overflow

ruby-on-rails heroku amazon-s3 carrierwave fog
Rectangle 27 14

There is nothing that can be done without a using a library like Uploadify. This is because the XMLHttpRequest (AJAX) standard has no support for file uploads. The only way you can really fake this is using an iFrame with Flash. Uploadify is the best of these options, and it has the best documentation. This is what has to be done on the client side (browser). Uploadify really isn't a ruby gem, its a collection of flash and js to allow the browser to 'fake it'.

On the server side, you can use carrierwave to support the uploads, but you need a way to get them there from the client side. Here is an extremely similar question which should give you the instructions that you need.

As noted in the other answer below, unless you need to support older browsers XHR2 has supported FormData for some time now. It's worth trying that if it's available to you and only falling back to other libraries for legacy support.

At this point this answer is outdated. HTML5 has the FormData and File API's that allow file uploads via AJAX. See here for more.

Does the Ruby on Rails CarrierWave gem work with Ajax? - Stack Overflo...

ruby-on-rails ajax jquery carrierwave
Rectangle 27 6

Looks like you want to upload to S3, but have not-public URLs. Instead of downloading the file from S3 and using send_file, you can redirect the user to the S3 authenticated URL. This URL will expire and only be valid for a little while (for the user to download).

resource.upload_url

I do get an authenticated url and the redirect_to method works. Presumably I'll have to tell my users to 'Right-click to save' or their browser might open images in the browser revealing the amazon url - which, while not being a problem technically, would just look a bit amateur. Or is there a way I could obscure the URL from the user? Thanks for the help.

@technix -- this is precisely what 37signals does with their basecamp file uploads. I wouldn't bother with right-click-to-save, but that's up to you.

ruby on rails - Carrierwave & Amazon S3 file downloading/uploading - S...

ruby-on-rails amazon-s3 carrierwave fog
Rectangle 27 3

if all you have to work with is a url like that you can send a HEAD request to the server to obtain the content type for the image. From that you can obtain the extension

require 'net/http'
require 'mime/types'

def get_extension(url)
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true if uri.scheme == 'https'
  request = Net::HTTP::Head.new(uri.request_uri)
  response = http.request(request)
  content_type = response['Content-Type']
  MIME::Types[content_type].first.extensions.first
end

ruby on rails - Carrierwave image extensions - Stack Overflow

ruby-on-rails ruby-on-rails-3 image upload carrierwave