2008年8月22日星期五

rails crop image use paperclip and jquery

More and more sites begin to allow user to crop their avatar.
After some time google, I haven't found a easy way to implement this in rails use jquery and paperclip.
So I think maybe this article is helpful.

First I install a jquery plugin imaareaselect , it works well.

I add it in the view,
 
<% content_for :head do %>
<%= javascript_include_tag 'jquery-areaselect' %>
<% javascript_tag do -%>
$(window).load(function () { $('#duck').imgAreaSelect({ x1: 120, y1: 90, x2: 280, y2: 210, onSelectEnd: set_crop });
});
function set_crop(img, selection){
$('#crop_left').val(selection.x1)
$('#crop_top').val(selection.y1)
$('#crop_width').val(selection.width)
$('#crop_height').val(selection.height)
}
<% end -%>
<% end %>


and these lines in a form

 

<%= hidden_field_tag "crop_left", "0" %>


<%= hidden_field_tag "crop_top", "0" %>


<%= hidden_field_tag "crop_width", "1" %>


<%= hidden_field_tag "crop_height", "1" %>



<%= image_tag current_user.photo.url(:large), :id => "duck" %>


then I write some codes in a moudle, this is the file:
def crop!( options = {} )
# setup the default params
options[:crop_left] ||= 0
options[:crop_top] ||= 0
options[:crop_width] ||= 100
options[:crop_height] ||= 100
# passed params could be strings, so convert them to ints/booleans
crop_l = options[:crop_left].to_i
crop_t = options[:crop_top].to_i
crop_w = options[:crop_width].to_i
crop_h = options[:crop_height].to_i
# call the appropriate crop method for the image processor we're using with attachment_fu
crop_with_paperclip! crop_l, crop_t, crop_w, crop_h
end
def crop_with_paperclip!(crop_l, crop_t, crop_w, crop_h)
dst = Tempfile.new("stream")
dst.binmode
src = File.join(RAILS_ROOT, "public/#{self.photo.url(:large)}")
command = <<-end_command
#{ Paperclip.path_for_command('convert') }
"#{src}"
-crop "#{crop_w}x#{crop_h}+#{crop_l}+#{crop_t}"
"#{File.expand_path(dst.path)}"
end_command
success = system(command.gsub(/\s+/, " "))
if success && $?.exitstatus != 0
raise PaperclipError, "There was an error processing this thumbnail"
end
thumb = Paperclip::Thumbnail.make(dst, "48x48#", nil, true)
thumb_path = File.join(RAILS_ROOT, "public/#{self.photo.url(:thumb)}")
begin
FileUtils.rm(thumb_path) if File.exist?(thumb_path)
rescue Errno::ENOENT => e
# ignore file-not-found, let everything else pass
end
result = thumb.stream_to(thumb_path)
thumb.close
result.close
end


I will extract this as a paperclip extention later. In fact, you can this with prototype too.

没有评论: