您好,登錄后才能下訂單哦!
由于之前做項目的時候有需求是需要實現(xiàn)裁剪圖片來做頭像并上傳到服務器,所以上網(wǎng)查詢了很多資料,也試用了許多案例,發(fā)現(xiàn)cropper插件裁剪是比較完善的,所以結(jié)合之前的使用情況,編寫了此案例。本案例是參考cropper站點實例,進行修改簡化。
option相關參數(shù)說明:
viewMode 顯示模式
Type: Number
Default: 0
Options:
0: the crop box is just within the container 裁剪框只能在 1內(nèi)移動
1: the crop box should be within the canvas 裁剪框 只能在 2圖片內(nèi)移動
2: the canvas should not be within the container 2圖片 不全部鋪滿1 (即縮小時可以有一邊出現(xiàn)空隙)
3: the container should be within the canvas 2圖片 全部鋪滿1 (即 再怎么縮小也不會出現(xiàn)空隙)
dragMode 拖動模式
Default: ‘crop'
Options:
‘crop': create a new crop box 當鼠標 點擊一處時根據(jù)這個點重新生成一個 裁剪框
‘move': move the canvas 可以拖動圖片
‘none': do nothing 圖片就不能拖動了
toggleDragModeOnDblclick: 默認true .是否允許 拖動模式 “crop” 跟“move” 的切換狀態(tài)。。即當點下為crop 模式,如果未松開拖動這時就是“move”模式。放開后又為“crop”模式。
preview: 截圖的顯示位置。類型:String
responsive:是否在窗口尺寸改變的時候重置cropper。類型:Boolean,默認值true。
checkImageOrigin:類型:Boolean,默認值true。默認情況下,插件會檢測圖片的源,如果是跨域圖片,圖片元素會被添加crossOriginclass,并會為圖片的url添加一個時間戳來使getCroppedCanvas變?yōu)榭捎?。添加時間戳會使圖片重新加載,以使跨域圖片能夠使用getCroppedCanvas。在圖片上添加crossOriginclass會阻止在圖片url上添加時間戳,及圖片的重新加載。
background:類型:Boolean,默認值true。是否在容器上顯示網(wǎng)格背景。 要想改背景,是直接改,cropper.css樣式中的 cropper-bg。
canvas(圖片)相關
movable:類型:Boolean,默認值true。是否允許移動圖片
rotatable:類型:Boolean,默認值true。是否允許旋轉(zhuǎn)圖片。
scalable: 默認 true 。 是否允許擴展圖片。(暫時不知道干嘛用)
zoomable: 默認true, 石頭允許縮放圖片。
zoomOnWheel: 默認 true 是否允許鼠標滾軸 縮放圖片
zoomOnTouch: 默認true 是否允許觸摸縮放圖片(觸摸屏上兩手指操作。)
wheelZoomRatio: 默認0.1 師表滾軸縮放圖片比例。即滾一下。圖片縮放多少。如 0.1 就是圖片的10%
crop(裁剪框)相關
aspectRatio裁剪框比例 默認NaN
例如:: 1 / 1,//裁剪框比例 1:1
modal:類型:Boolean,默認值true。是否在剪裁框上顯示黑色的模態(tài)窗口。
cropBoxMovable:默認true ,是否允許拖動裁剪框
cropBoxResizable:默認 true,//是否允許拖動 改變裁剪框大小
autoCrop:類型:Boolean,默認值true。是否允許在初始化時自動出現(xiàn)裁剪框。
autoCropArea:類型:Number,默認值0.8(圖片的80%)。0-1之間的數(shù)值,定義自動剪裁框的大小。
highlight:類型:Boolean,默認值true。是否在剪裁框上顯示白色的模態(tài)窗口。
guides:類型:Boolean,默認值true。是否在剪裁框上顯示虛線。
center: 默認true 是否顯示裁剪框 中間的+ restore : 類型:Boolean,默認值true 是否
調(diào)整窗口大小后恢復裁剪區(qū)域。
大小相關
minContainerWidth:類型:Number,默認值200。容器的最小寬度。
minContainerHeight:類型:Number,默認值100。容器的最小高度。
minCanvasWidth:類型:Number,默認值0。canvas 的最小寬度(image wrapper)。
minCanvasHeight:類型:Number,默認值0。canvas 的最小高度(image wrapper)。
監(jiān)聽觸發(fā)的方法
build:類型:Function,默認值null。build.cropper
事件的簡寫方式。 ====== ??丶跏蓟皥?zhí)行
built:類型:Function,默認值null。built.cropper
事件的簡寫方式。 ====== 空間初始化完成后執(zhí)行
dragstart:類型:Function,默認值null。dragstart.cropper
事件的簡寫方式。 ====== 拖動開始執(zhí)行
dragmove:類型:Function,默認值null。dragmove.cropper
事件的簡寫方式。====== 拖動移動中執(zhí)行
dragend:類型:Function,默認值null。dragend.cropper
事件的簡寫方式。====== 拖動結(jié)束執(zhí)行
zoomin:類型:Function,默認值null。zoomin.cropper
事件的簡寫方式。 ====== 縮小執(zhí)行
zoomout:類型:Function,默認值null。zoomout.cropper
事件的簡寫方式。 ====== 放大執(zhí)行
index.html代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="external nofollow" > <link rel="stylesheet" href="css/cropper.css" rel="external nofollow" > <link rel="stylesheet" href="css/main.css" rel="external nofollow" > <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <!--[if lt IE 8]> <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a rel="external nofollow" >upgrade your browser</a> to improve your experience.</p> <![endif]--> <!-- Content --> <div class="container" > <div class="row"> <div class="col-md-9"> <!-- <h4>Demo:</h4> --> <div class="img-container"> ![](images/picture.jpg) </div> </div> <div class="col-md-3"> <!-- <h4>Preview:</h4> --> <div class="docs-preview clearfix"> <div class="img-preview preview-lg"></div> </div> </div> </div> <div class="row"> <div class="col-md-9 docs-buttons"> <!-- <h4>Toolbar:</h4> --> <div class="btn-group"> <button type="button" class="btn btn-primary" data-method="zoom" data-option="0.1" title="Zoom In"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("zoom", 0.1)"> 放大 </span> </button> <button type="button" class="btn btn-primary" data-method="zoom" data-option="-0.1" title="Zoom Out"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("zoom", -0.1)"> 縮小 </span> </button> </div> <div class="btn-group"> <button type="button" class="btn btn-primary" data-method="move" data-option="-10" data-second-option="0" title="Move Left"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("move", -10, 0)"> 左移 </span> </button> <button type="button" class="btn btn-primary" data-method="move" data-option="10" data-second-option="0" title="Move Right"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("move", 10, 0)"> 右移 </span> </button> <button type="button" class="btn btn-primary" data-method="move" data-option="0" data-second-option="-10" title="Move Up"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("move", 0, -10)"> 上移 </span> </button> <button type="button" class="btn btn-primary" data-method="move" data-option="0" data-second-option="10" title="Move Down"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("move", 0, 10)"> 下移 </span> </button> </div> <div class="btn-group"> <button type="button" class="btn btn-primary" data-method="rotate" data-option="-90" title="Rotate Left"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("rotate", -90)"> 左轉(zhuǎn)90º </span> </button> <button type="button" class="btn btn-primary" data-method="rotate" data-option="90" title="Rotate Right"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("rotate", 90)"> 右轉(zhuǎn)90º </span> </button> </div> <div class="btn-group"> <button type="button" class="btn btn-primary" data-method="reset" title="Reset"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("reset")"> 刷新 </span> </button> <label class="btn btn-primary btn-upload" for="inputImage" title="Upload image file"> <input type="file" class="sr-only" id="inputImage" name="file" accept=".jpg,.jpeg,.png,.gif,.bmp,.tiff"> <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="Import image with Blob URLs"> 上傳圖片 </span> </label> </div> <div class="btn-group btn-group-crop"> <button class="btn btn-primary" data-method="getCroppedCanvas" data-option="{ "width": 180, "height": 90 }" type="button"> 上傳頭像 </button> </div> <!-- Show the cropped image in modal --> <div class="modal fade docs-cropped" id="getCroppedCanvasModal" aria-hidden="true" aria-labelledby="getCroppedCanvasTitle" role="dialog" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h6 class="modal-title" id="getCroppedCanvasTitle">Cropped</h6> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"></div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <a class="btn btn-primary" id="download" href="javascript:void(0);" rel="external nofollow" download="cropped.jpg">Download</a> </div> </div> </div> </div><!-- /.modal --> </div><!-- /.docs-buttons --> </div> <!-- Scripts --> <script src="js/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script> <script src="js/cropper.js"></script> <script src="js/main.js"></script> </body> </html>
cropper.js部分參數(shù)代碼:
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : (factory(global.$)); }(this, (function ($) { 'use strict'; $ = 'default' in $ ? $['default'] : $; var DEFAULTS = { // Define the view mode of the cropper viewMode: 0, // 0, 1, 2, 3 顯示 // Define the dragging mode of the cropper dragMode: 'crop', // 'crop', 'move' or 'none' // Define the aspect ratio of the crop box aspectRatio: NaN, // An object with the previous cropping result data data: null, // A selector for adding extra containers to preview preview: '', // Re-render the cropper when resize the window responsive: true, // Restore the cropped area after resize the window restore: true, // Check if the current image is a cross-origin image checkCrossOrigin: true, // Check the current image's Exif Orientation information checkOrientation: true, // Show the black modal modal: true, // Show the dashed lines for guiding guides: true, // Show the center indicator for guiding center: true, // Show the white modal to highlight the crop box highlight: true, // Show the grid background background: true, // Enable to crop the image automatically when initialize autoCrop: true, // Define the percentage of automatic cropping area when initializes autoCropArea: 0.8, // Enable to move the image movable: true, // Enable to rotate the image rotatable: true, // Enable to scale the image scalable: true, // Enable to zoom the image zoomable: true, // Enable to zoom the image by dragging touch zoomOnTouch: true, // Enable to zoom the image by wheeling mouse zoomOnWheel: true, // Define zoom ratio when zoom the image by wheeling mouse wheelZoomRatio: 0.1, // Enable to move the crop box cropBoxMovable: true, // Enable to resize the crop box cropBoxResizable: true, // Toggle drag mode between "crop" and "move" when click twice on the cropper toggleDragModeOnDblclick: true, // Size limitation minCanvasWidth: 0, minCanvasHeight: 0, minCropBoxWidth: 0, minCropBoxHeight: 0, minContainerWidth: 200, minContainerHeight: 100, // Shortcuts of events ready: null, cropstart: null, cropmove: null, cropend: null, crop: null, zoom: null };
main.js 代碼如下:
$(function () { 'use strict';//表示強規(guī)則 var console = window.console || { log: function () {} }; var URL = window.URL || window.webkitURL; var $image = $('#image'); var $download = $('#download'); //獲取圖片截取的位置 var $dataX = $('#dataX'); var $dataY = $('#dataY'); var $dataHeight = $('#dataHeight'); var $dataWidth = $('#dataWidth'); var $dataRotate = $('#dataRotate'); var $dataScaleX = $('#dataScaleX'); var $dataScaleY = $('#dataScaleY'); var options = { aspectRatio: 1 / 1, //裁剪框比例1:1 preview: '.img-preview', crop: function (e) { $dataX.val(Math.round(e.x)); $dataY.val(Math.round(e.y)); $dataHeight.val(Math.round(e.height)); $dataWidth.val(Math.round(e.width)); $dataRotate.val(e.rotate); $dataScaleX.val(e.scaleX); $dataScaleY.val(e.scaleY); } }; var originalImageURL = $image.attr('src'); var uploadedImageURL; // Tooltip $('[data-toggle="tooltip"]').tooltip(); // Cropper $image.on({ ready: function (e) { console.log(e.type); }, cropstart: function (e) { console.log(e.type, e.action); }, cropmove: function (e) { console.log(e.type, e.action); }, cropend: function (e) { console.log(e.type, e.action); }, crop: function (e) { console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY); }, zoom: function (e) { console.log(e.type, e.ratio); } }).cropper(options); // Buttons if (!$.isFunction(document.createElement('canvas').getContext)) { $('button[data-method="getCroppedCanvas"]').prop('disabled', true); } if (typeof document.createElement('cropper').style.transition === 'undefined') { $('button[data-method="rotate"]').prop('disabled', true); $('button[data-method="scale"]').prop('disabled', true); } // Download if (typeof $download[0].download === 'undefined') { $download.addClass('disabled'); } // Options $('.docs-toggles').on('change', 'input', function () { var $this = $(this); var name = $this.attr('name'); var type = $this.prop('type'); var cropBoxData; var canvasData; if (!$image.data('cropper')) { return; } if (type === 'checkbox') { options[name] = $this.prop('checked'); cropBoxData = $image.cropper('getCropBoxData'); canvasData = $image.cropper('getCanvasData'); options.ready = function () { $image.cropper('setCropBoxData', cropBoxData); $image.cropper('setCanvasData', canvasData); }; } else if (type === 'radio') { options[name] = $this.val(); } $image.cropper('destroy').cropper(options); }); // Methods // 點擊開始計算圖片位置,獲取位置 $('.docs-buttons').on('click', '[data-method]', function () { var $this = $(this); var data = $this.data(); var $target; var result; if ($this.prop('disabled') || $this.hasClass('disabled')) { return; } if ($image.data('cropper') && data.method) { data = $.extend({}, data); // Clone a new one if (typeof data.target !== 'undefined') { $target = $(data.target); if (typeof data.option === 'undefined') { try { data.option = JSON.parse($target.val()); } catch (e) { console.log(e.message); } } } if (data.method === 'rotate') { $image.cropper('clear'); } result = $image.cropper(data.method, data.option, data.secondOption); if (data.method === 'rotate') { $image.cropper('crop'); } switch (data.method) { case 'scaleX': case 'scaleY': $(this).data('option', -data.option); break; case 'getCroppedCanvas': //上傳頭像 if (result) { var imgBase=result.toDataURL('image/jpeg'); var data={imgBase:imgBase}; $.post('/docs/upload.php',data,function(ret){ if(ret=='true'){ alert('上傳成功'); }else{ alert('上傳失敗'); } },'text'); } break; case 'destroy': if (uploadedImageURL) { URL.revokeObjectURL(uploadedImageURL); uploadedImageURL = ''; $image.attr('src', originalImageURL); } break; } if ($.isPlainObject(result) && $target) { try { $target.val(JSON.stringify(result)); } catch (e) { console.log(e.message); } } } }); // Keyboard $(document.body).on('keydown', function (e) { if (!$image.data('cropper') || this.scrollTop > 300) { return; } switch (e.which) { case 37: e.preventDefault(); $image.cropper('move', -1, 0); break; case 38: e.preventDefault(); $image.cropper('move', 0, -1); break; case 39: e.preventDefault(); $image.cropper('move', 1, 0); break; case 40: e.preventDefault(); $image.cropper('move', 0, 1); break; } }); // Import image var $inputImage = $('#inputImage'); if (URL) { $inputImage.change(function () { var files = this.files; var file; if (!$image.data('cropper')) { return; } if (files && files.length) { file = files[0]; if (/^image\/\w+$/.test(file.type)) { if (uploadedImageURL) { URL.revokeObjectURL(uploadedImageURL); } uploadedImageURL = URL.createObjectURL(file); $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options); $inputImage.val(''); } else { window.alert('Please choose an image file.'); } } }); } else { $inputImage.prop('disabled', true).parent().addClass('disabled'); } });
使用canvas生成的截圖轉(zhuǎn)換生成base64代碼。
后臺處理base64代碼片段(PHP服務端)。
upload.php代碼如下:
<?php error_reporting(0);//禁用錯誤報告 if (IS_POST) { header('Content-type:text/html;charset=utf-8'); $base64_image_content = $_POST['imgBase']; //將base64編碼轉(zhuǎn)換為圖片保存 if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) { $type = $result[2]; $new_file = "./uploads/"; if (!file_exists($new_file)) { //檢查是否有該文件夾,如果沒有就創(chuàng)建,并給予最高權限 mkdir($new_file, 0700); } $img=time() . ".{$type}"; $new_file = $new_file . $img; //將圖片保存到指定的位置 if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) { echo 'true'; }else{ echo 'false'; } }else{ echo 'false'; } } ?>
實現(xiàn)效果:
選擇要截取的圖片位置,按“上傳頭像”按鈕,截取的圖片就上傳并保存到服務器本站點目錄的uploads文件夾中。
總結(jié)
以上所述是小編給大家介紹的Cropper.js 實現(xiàn)裁剪圖片并上傳(PC端) ,希望對大家有所幫助,
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。