I am working on the ability to crop images using carrierwave and Jcrop. Its a combination of Railscasts episode 182 and 253. I have cropping working but it crops the original.
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.
Here is my solution.
user.rb
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
account_controller.rb
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
profile_uploader.rb
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
crop.html.erb
<% content_for :head do %>
<%= stylesheet_link_tag "jquery.Jcrop" %>
<%= javascript_include_tag "jquery.Jcrop.min" %>
<% end %>
<%= image_tag @account.profile_url(:large), :id => "cropbox" %>
Preview
<%= image_tag @account.profile_url(:large), :id => "preview" %>
<%= 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 %>
<%= f.submit "Crop" %>
<% end %>
style.css
.preview {
width:100px;
height:100px;
overflow:hidden;
}