В этом HOWTO я раскажу вам как обрезать фотографию до нужного вам размера и залить её на сервер с помощью Ruby on Rails.
Итак, для наших целей наиболее подходят 2 плагина:
Prototype JavaScript Image Cropper UI
jQuery image crop plugin
Написаны они, как вы понимает на 2 разных библиотеках, и так как в моем проекте уже был установлен JRails и второй плагин мне показался более продвинутым, я остановил свой выбор на нем. Но суть примера от этого не меняется.
Я не буду тратить время на рассказ о том, как сделать Hello world на RoR, поэтому просто создадим модель и контроллер:
$ script/generate model upload description:string
$ script/generate paperclip upload photo
$ script/generate controller uploads
#models/upload.rb
class Upload < ActiveRecord::Base
has_attached_file :photo,
:styles => {
:thumb => ["100x100", :jpg],
:pagesize => ["500x400", :jpg],
},
:default_style => :pagesize
end
Подключаем библиотеки:
# views/layouts/application.html.erb
<%= javascript_include_tag 'lib/jquery.min.js' %>
<%= javascript_include_tag 'cropper/jquery.jcrop.js' %>
И делаем представление «Edit»:
# view/uploads/edit.html.erb
<script type="text/javascript" language="JavaScript">
function showCoords( c ) {
$( 'upload_x1' ).val(c.x);
$( 'upload_y1' ).val(c.y);
$( 'upload_width' ).val(c.w);
$( 'upload_height' ).val(c.h);
}
$(function(){
$('#jcrop_target').Jcrop({
onChange: showCoords,
onSelect: showCoords
});
});
</script>
<h1>Editing upload</h1>
<% form_for(@upload) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :description %><br />
<%= f.text_field :description %>
</p>
<!-- CROP FORM -->
<div id='jcrop_target'>
<%= image_tag @upload.photo.url, :id => 'cropimage' %>
</div>
<div id='cropresults'>
<%= f.label 'x1' %>
<%= f.text_field 'x1', :size => 6 %>
<br />
<%= f.label 'y1' %>
<%= f.text_field 'y1', :size => 6 %>
<br />
<%= f.label 'width' %>
<%= f.text_field 'width', :size => 6 %>
<br />
<%= f.label 'height' %>
<%= f.text_field 'height', :size => 6 %>
<br />
</div> <!-- cropresults -->
<!-- END CROP FORM -->
<p>
<%= f.submit "Update" %>
</p>
<% end %>
Почти все, добавляем событие update:
# controllers/uploads_controller.rb
def update
@upload = Upload.find params[:id]
if @upload.update_attributes params[:upload]
flash[:notice] = 'Upload was successfully updated.'
redirect_to @upload
else
render :action => "edit"
end
end
И наконец вот она, основная магия:
# models/upload/upload.rb
require 'RMagick'
attr_accessor :x1, :y1, :width, :height
def update_attributes(att)
scaled_img = Magick::ImageList.new(self.photo.path)
orig_img = Magick::ImageList.new(self.photo.path(:original))
scale = orig_img.columns.to_f / scaled_img.columns
args = [ att[:x1], att[:y1], att[:width], att[:height] ]
args = args.collect { |a| a.to_i * scale }
orig_img.crop!(*args)
orig_img.write(self.photo.path(:original))
self.photo.reprocess!
self.save
super(att)
end
Здесь мы рассчитываем коэффициент масштабирования. Далее мы готовим четыре аргумента для RMagick crop функции, которая ожидает X1, Y2, ширину и высоту. Изображение изменяется и записывается заменив собой оригинал.Все, всем спасибо за внимание. Здесь пример для prototype.