概述
让我们使用Cropper.js在Rails中使用修整功能实现图像上传功能。
源代码如下。
https://github.com/Tak-Iwamoto/jquery-cropper-rails
环境
Rails 5.2.2
Bootstrap 4.3.1
活动存储
mini_magick 4.9.4
活动存储
执行以下命令以使用
active_storage。
载入Cropper.js
https://github.com/fengyuanchen/cropperjs
从上面的github中获取cropper.min.js和cropper.min.css,并将它们放置在Rails中。建议将第三方库放在供应商目录中,在供应商中创建资产/ javascripts和资产/样式表目录,然后分别放置cropper.min.js和cropper.min.css。
https://github.com/fengyuanchen/jquery-cropper
另外,从上述github获取jquery-cropper.min.js以使用JQuery并将其放置在Rails中。最后,如下编辑application.js和application.scss。
application.js
1 2 3 4 5 6 7 8 9 10 | //= require rails-ujs //= require jquery //= require jquery_ujs //= require cropper.min.js //= require jquery-cropper.min.js //= require activestorage //= require turbolinks //= require_tree . //= require popper //= require bootstrap-sprockets |
application.scss
1 2 3 4 | *= require_tree . *= require cropper.min.css *= require_self */ |
您现在可以使用Cropper.js。
创建模型和控制器
为演示创建用户模型和控制器。
user.rb
1 2 3 4 | class User < ApplicationRecord attr_accessor :x, :y, :width, :height has_one_attached :image end |
users_controller.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(user_params) @user.save session[:crop_x] = user_params[:x] session[:crop_y] = user_params[:y] session[:crop_width] = user_params[:width] session[:crop_height] = user_params[:height] redirect_to user_path @user end def show @user = User.find(params[:id]) end private def user_params params.require(:user).permit(:image, :x, :y, :width, :height) end end |
我在会话中保留了使用Cropper.js进行修剪的结果的参数,并在以后显示图像时使用它,但是我觉得此方法并不简单...使用active_storage处理的图像我不知道如何保存,所以我是用这种方式做的,但是我认为可能还有另一种好方法。
图片上传表格
创建一个用于上传裁剪图像的表格。
new.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="preview" style='overflow:hidden'> <div id="beforeUpload"> <%= icon("fas fa-4x fw","file-image")%> </div> <img _src="" id="croppedImage"> </div> <%= form_with model: @user, url: users_path do |f| %> <%= f.file_field :image%> <%= f.hidden_field :x, id:"dataX"%> <%= f.hidden_field :y, id:"dataY"%> <%= f.hidden_field :width, id:"dataWidth"%> <%= f.hidden_field :height, id:"dataHeight"%> <%= f.submit "button", id:"btnUpload", class: 'btn btn-success'%> <% end %> <div class="modal fade" id="cropModal" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-body"> <div class="img-container"> <img _src="" id="imageModal" alt="picture"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" id="btn-save" data-dismiss="modal">Save</button> </div> </div> </div> </div> </div> </div> </div> |
裁剪的图像显示为
使用
在
创建以下html以显示裁剪的图像。
<%= image_tag @user.image.variant(crop: "#{session[:crop_width]}x#{session[:crop_height]}+#{session[:crop_x]}+#{session[:crop_y]}") %><br>
现在,创建以下javascript文件以执行修剪过程。
crop_image.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | $(function () { let $image = $('#imageModal'), $img_field = $('#user_image'), $croppedImage = $('#croppedImage'), $cropModal = $('#cropModal'), $beforeUpload = $('#beforeUpload'), $button = $('#btn-save'), $dataX = $('#dataX'), $dataY = $('#dataY'), $dataWidth = $('#dataWidth'), $dataHeight = $('#dataHeight'); let options = { dragmode: 'crop', aspectRatio: 1/1, restore: false, guides: false, center: false, highlight: true, cropBoxMovable: true, cropBoxResizable: true, modal: true, crop: (e) => { $dataX.val(Math.round(e.detail.x)); $dataY.val(Math.round(e.detail.y)); $dataWidth.val(Math.round(e.detail.width)); $dataHeight.val(Math.round(e.detail.height)); } }; // when file upload $img_field.change((e) => { $image.cropper('destroy').removeAttr('src'); file = e.target.files[0]; reader = new FileReader(); if (file.type.indexOf('image') < 0) { window.alert("画像を選択してください"); return ; } reader.onload = ((e) => { $image.attr('src',""); $image.attr('src', e.target.result); $cropModal.modal('show'); $cropModal.on('shown.bs.modal', () => { $image.cropper(options); }); }); reader.readAsDataURL(file); }) // onclick save button $button.click(() => { imgCropping(); }); // modalを閉じたとき、cropper要素を初期化 $cropModal.on('hidden.bs.modal',function() { $image.cropper('destroy').removeAttr('src'); let $cropperContainer = $('.cropper-container'); $cropperContainer.remove(); }); function imgCropping() { if (!croppable) { alert('トリミングする画像が用意されていません') return false; } $beforeUpload.hide(); let croppedData = $image.cropper('getCroppedCanvas').toDataURL(); $croppedImage.attr('src', croppedData); $cropModal.modal('hide'); } }); |
$ img_field指定ID为user_image的DOM,但是在html端没有这样的ID。请注意,当您使用form_with创建file_field时,Rails会自动创建一个
选项设置如何裁剪图像。
显示模态时,使用在
另外,当创建裁剪实例时,将创建
这就是
的全部。