Pages

Wednesday, 9 April 2014

Crop image In ruby using Jcrop

Steps to Install

1. Write the following gem in Gemfile
 
 gem 'paperclip', '3.1.4'
 gem 'cocaine', '0.3.2'
 gem 'rmagick'

 use the versions same as given otherwise the call will be recursive

2. Run from console  `bundle install`

3. Now write the following code in the post/_form.html.erb

   Images:
   <p>
     <%= f.file_field :avatar %>
   </p>

4. Write code in the view posts/crop.html.erb

   <% content_for (:head) do %>
      <%= stylesheet_link_tag "jquery.Jcrop" %>
     
     <%= javascript_include_tag "jquery.Jcrop.min" %>
     
     <script type="text/javascript">
       $(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;
       $('#preview').css({
         width: Math.round(rx * <%= @post.avatar_geometry(:large).width %>) + 'px',
         height: Math.round(ry * <%= @post.avatar_geometry(:large).height %>) + 'px',
         marginLeft: '-' + Math.round(rx * coords.x) + 'px',
         marginTop: '-' + Math.round(ry * coords.y) + 'px'
       });

var ratio = <%= @post.avatar_geometry(:original).width %> / <%=   @post.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));  
     }
     </script>
   <% end %>

   <%= image_tag @post.avatar.url(:large), :id => "cropbox" %>
   <br/>

   <h4>Preview</h4>
   <div style="width: 100px; height: 100px; overflow: hidden;">
     <%= image_tag @post.avatar.url(:large), :id => "preview" %>
   </div>

   <%= form_for @post do |f| %>a
     <% for attribute in [:crop_x, :crop_y, :crop_w, :crop_h] %>
       <%= f.text_field attribute, :id => attribute %>
     <% end %>
     <p><%= f.submit "Crop" %></p>
   <% end %>

   Write the following BOLD code in layouts/application.html.erb

   <%= stylesheet_link_tag    "application", :media => "all" %>
   <%= javascript_include_tag "application" %>
   <%= csrf_meta_tags %>
   
   <%= yield(:head) %>

5. Now in post.rb

   class Post < ActiveRecord::Base
     
     attr_accessible :content, :user_id, :vid, :duration, :avatar, :crop_x, :crop_y, :crop_w, :crop_h
    
     has_attached_file :avatar, :styles  => { :small => "100x100#" ,:large => "500x500>" }, :processors => [:cropper]
     
     attr_accessor :crop_x, :crop_y, :crop_w, :crop_h

     after_update :reprocess_avatar, :if => :cropping?

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

     def avatar_geometry(style = :original)
       @geometry ||= {}
       @geometry[style] ||= Paperclip::Geometry.from_file(avatar.path(style))
     end

     private
     
     def reprocess_avatar
       avatar.reprocess!
     end
   
   end

6. Write code in post controller

   def create
     @post = Post.new(params[:post])

     respond_to do |format|
       if @post.save
         if params[:post][:avatar].blank?
           format.html { redirect_to @post, notice: 'Photo was successfully created.' }
         else
           format.html { render :action => 'crop' }
         end
       else
         format.html { render action: "new" }
         format.json { render json: @post.errors, status: :unprocessable_entity }
       end
     end
   end

   def update
     @post = Post.find(params[:id])
     if @post.update_attributes(params[:post])
       flash[:notice] = 'Post was successfully updated.'

         if params[:post][:avatar].blank?
           redirect_to(@post)
         else
           render :action => 'crop'
         end
     else
         render :action => "edit"
     end
   end

7. In development.rb . it’s Optional for paperclip

   Paperclip.options[:command_path] = "/usr/local/bin"

8. Now create a folder in lib named paperclip_processors and file cropper.rb and write code

   module Paperclip
     class Cropper < Thumbnail
       def transformation_command

         if crop_command
           crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ')
         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

References:-
http://railsifyme.wordpress.com/2013/05/28/paperclip-cropping-error-using-jcrop-and-s3/ http://goo.gl/Apykh