Cropping Images using jCrop jQuery plugin in Rails
Thêm gem rmagick và carierwave vào Gemfile. gem 'rmagick' gem 'carrierwave' Trên Mac, bạn có thể cài đặt imagemagick sữ dụng brew brew install imagemagick Tạo ra một uploader tên là Avatar rails generate uploader Avatar Khởi tạo một model User có 2 trường là name và avatar rails ...
Thêm gem rmagick và carierwave vào Gemfile.
gem 'rmagick' gem 'carrierwave'
Trên Mac, bạn có thể cài đặt imagemagick sữ dụng brew
brew install imagemagick
Tạo ra một uploader tên là Avatar
rails generate uploader Avatar
Khởi tạo một model User có 2 trường là name và avatar
rails g model user name avatar.
Thiết lập carrirwave uploader trong model User
class User < ApplicationRecord mount_uploader :avatar, AvatarUploader end
Tạo ra một controller user
rails g controller users
Chạy migration
rails db:migrate
Định nghĩa resource trong routes.rb
Rails.application.routes.draw do resources :users root to: 'users#index' end
Thêm đoạn code sau vào file uploaders/avatar_uploader.rb
include CarrierWave::RMagick version :thumb do resize_to_fill(100, 100) end
Trong file uploaders/avatar_uploader.rb, thêm large version của hình ảnh và phương thức crop.
version :large do resize_to_limit(600, 600) end def crop if model.crop_x.present? resize_to_limit(600, 600) manipulate! do |img| x = model.crop_x.to_i y = model.crop_y.to_i w = model.crop_w.to_i h = model.crop_h.to_i img.crop!(x, y, w, h) end end end
Thay đổi action update và create trong users controller để xữ lý chức năng crop.
def update @user = User.find(params[:id]) if @user.update_attributes(allowed_params) if params[:user][:avatar].present? render :crop else redirect_to @user, notice: "Successfully updated user." end else render :new end end def create @user = User.new(allowed_params) if @user.save if params[:user][:avatar].present? render :crop else redirect_to @user, notice: "Successfully created user." end else render :new end end
Thêm file crop.html.erb vào thư mục app/views/users.
<h1>Crop Avatar</h1> <%= image_tag @user.avatar_url(:large), id: "cropbox" %> <h4>Preview</h4> <div style="awidth:100px; height:100px; overflow:hidden"> <%= image_tag @user.avatar.url(:large), :id => "preview" %> </div> <%= form_for @user do |f| %> <% %w[x y w h].each do |attribute| %> <%= f.hidden_field "crop_#{attribute}" %> <% end %> <div class="actions"> <%= f.submit "Crop" %> </div> <% end %>
Thêm đoạn code sau vào model User:
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h after_update :crop_avatar def crop_avatar avatar.recreate_versions! if crop_x.present? end
Download jcrop jquery plugin từ jcrop website. Copy file jquery.Jcrop.css vào thưc mục vendor/assets/stylesheets và file jquery.Jcrop.js vào thư mục vendor/assets/javascripts. Trong file application.js, thêm:
//= require jquery.Jcrop
Trong file application.css, thêm:
*= require jquery.Jcrop
File users.coffee:
jQuery -> new AvatarCropper() class AvatarCropper constructor: -> $('#cropbox').Jcrop aspectRatio: 1 setSelect: [0, 0, 600, 600] onSelect: @update onChange: @update update: (coords) => $('#user_crop_x').val(coords.x) $('#user_crop_y').val(coords.y) $('#user_crop_w').val(coords.w) $('#user_crop_h').val(coords.h) @updatePreview(coords) updatePreview: (coords) => $('#preview').css awidth: Math.round(100/coords.w * $('#cropbox').awidth()) + 'px' height: Math.round(100/coords.h * $('#cropbox').height()) + 'px' marginLeft: '-' + Math.round(100/coords.w * coords.x) + 'px' marginTop: '-' + Math.round(100/coords.h * coords.y) + 'px'
Nó sẽ làm việc ngay bây giờ. Tuy nhiên, bức ảnh sẽ vẫn hiển thị những phần chưa được cắt. Để fix nó, thêm process :crop vào version :thumb trong avatar_uploader.rb
version :thumb do process :crop resize_to_fill(100, 100) end
https://rubyplus.com/articles/3951-Cropping-Images-using-jCrop-jQuery-plugin-in-Rails-5