#182 Cropping Images (revised)
Allow users to interactively crop uploaded images using Jcrop and Carrierwave. Includes a live preview that shows the resulting image.
- Download:
- source codeProject Files in Zip (533 KB)
- mp4Full Size H.264 Video (25.2 MB)
- m4vSmaller H.264 Video (13.1 MB)
- webmFull Size VP8 Video (17.2 MB)
- ogvFull Size Theora Video (26.7 MB)
Resoures
models/user.rb
class User < ActiveRecord::Base mount_uploader :avatar, AvatarUploader attr_accessor :crop_x, :crop_y, :crop_w, :crop_h after_update :crop_avatar def crop_avatar avatar.recreate_versions! if crop_x.present? end end
app/uploaders/avatar_uploader.rb
class AvatarUploader < CarrierWave::Uploader::Base include CarrierWave::RMagick storage :file # 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 version :large do resize_to_limit(600, 600) end version :thumb do process :crop resize_to_fill(100, 100) end def crop if model.crop_x.present? resize_to_limit(600, 600) manipulate! do |img| x = model.crop_x.to_i y = model.crop_y.to_i w = model.crop_w.to_i h = model.crop_h.to_i img.crop!(x, y, w, h) end end end end
users_controller.rb
if params[:user][:avatar].present? render :crop else redirect_to @user, notice: "Successfully created user." end
crop.html.erb
<h1>Crop Avatar</h1> <%= image_tag @user.avatar_url(:large), id: "cropbox" %> <h4>Preview</h4> <div style="width:100px; height:100px; overflow:hidden"> <%= image_tag @user.avatar.url(:large), :id => "preview" %> </div> <%= form_for @user do |f| %> <% %w[x y w h].each do |attribute| %> <%= f.hidden_field "crop_#{attribute}" %> <% end %> <div class="actions"> <%= f.submit "Crop" %> </div> <% end %>
app/assets/javascripts/application.js
//= require jquery.Jcrop
app/assets/stylesheets/application.css
*= require jquery.Jcrop
app/assets/javascripts/user.js.coffee
jQuery -> new AvatarCropper() class AvatarCropper constructor: -> $('#cropbox').Jcrop aspectRatio: 1 setSelect: [0, 0, 600, 600] onSelect: @update onChange: @update update: (coords) => $('#user_crop_x').val(coords.x) $('#user_crop_y').val(coords.y) $('#user_crop_w').val(coords.w) $('#user_crop_h').val(coords.h) @updatePreview(coords) updatePreview: (coords) => $('#preview').css width: Math.round(100/coords.w * $('#cropbox').width()) + 'px' height: Math.round(100/coords.h * $('#cropbox').height()) + 'px' marginLeft: '-' + Math.round(100/coords.w * coords.x) + 'px' marginTop: '-' + Math.round(100/coords.h * coords.y) + 'px'