Cropping Images using jCrop jQuery plugin in Rails
Bài đăng này đã không được cập nhật trong 7 năm
Cài đặt gem carierwave
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
Xử lý crop image
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="width: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
width: Math.round(100/coords.w * $('#cropbox').width()) + '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
Tham khảo
https://rubyplus.com/articles/3951-Cropping-Images-using-jCrop-jQuery-plugin-in-Rails-5
All rights reserved