Monday, January 17, 2011

JCrop with Paper Clip Plugin

This posts will help you to integrate JCrop plugin along with the paper clip. (Suitable for Rails 3 migration)

In our application we have a create a user model that is set to use paper clip plugin.

User Model:

class User < ActiveRecord::Base has_attached_file :avatar, :styles => { :small => "100x100#", :large => "500x500>" }, :processors => [:cropper]



after_update :reprocess_avatar, :if => :cropping?

attr_accessor :crop_x, :crop_y, :crop_w, :crop_h

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


#To restore the original image after it is cropped. The size can vary.
def avatar_geometry(style = :original)
@geometry ||= {}
@geometry[style] ||= Paperclip::Geometry.from_file avatar.path(style)
end


# To reprocess the attached file if we’re cropping it.
private

def reprocess_avatar

avatar.reprocess!

end
end



User Controller:

def create

@user = User.new(params[:user])

if @user.save
flash[:notice] = 'User was successfully created.'
if params[:user][:avatar].blank?

redirect_to(@user)
else
render :action => 'cropping'
end
else
render :action => 'new'
end
end

# PUT /users/1
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:notice] = 'User was successfully updated.'

if params[:user][:avatar].blank?
redirect_to(@user)
else

render :action => 'cropping'
end
else
render :action => "edit"
end
end


Cropping.html file should have the following set


function update_crop(coords) {

var ratio = <%= @user.avatar_geometry(:original).width %> /
<%= @user.avatar_geometry(:large).width %>;
$('#crop_x').val(Math.floor(coords.x * ratio));
$('#crop_y').val(Math.floor(coords.y * ratio));

$('#crop_w').val(Math.floor(coords.w * ratio));
$('#crop_h').val(Math.floor(coords.h * ratio));
}





Avatar:
<%= image_tag @user.avatar.url(:large), :id => "cropbox" %>


<% form_for @user do |f| %>
<%= f.text_field :crop_x, :id => 'crop_x' %>

<%= f.text_field :crop_y, :id => 'crop_y' %>

<%= f.text_field :crop_w, :id => 'crop_w' %>

<%= f.text_field :crop_h, :id => 'crop_h' %>

<%= f.submit "Crop!" %>
<% end %>

<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>


Show.erb file can contain

Name:
<%=h @user.name %>


Avatar:
<%= image_tag @user.avatar.url(:large) %>
<%= image_tag @user.avatar.url(:small) %>


<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>


lib\paperclip_processors should have cropper.rb with the following code

module Paperclip
class Cropper < Thumbnail def transformation_command if crop_command crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ') # super returns an array like this: ["-resize", "100x", "-crop", "100x100+0+0", "+repage"] else super end end def crop_command target = @attachment.instance if target.cropping? ["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"] end end end end Important steps to remember:

Move cropper.rb to the folder config\initializers
Remember to add crop_x, crop_y, Crop_w and crop_h to the list of your accessible attributes IF you have such a list:
attr_accessible :avatar, :crop_x, :crop_y, :crop_w, :crop_h

5. Added this line to my gemfile:
gem 'paperclip'

6. bundle install
Added jquery.Jcrop.min.js, jquery-1.4.3.min.js in public\javascripts folder

9. added Jcrop.gif and jquery.Jcrop.css in public\stylesheets folder

10. Added <%= yield(:head) %> in the head section in the application.html.erb file (needed for sample above)


http://asciicasts.com/episodes/182-cropping-images - This post helps you to understand in detail for Rails 2.3.8.

No comments:

Post a Comment