https://blog.csdn.net/qq727013465/article/details/51823231
我的需求功能:在手機端實現上傳頭像,帶裁剪框。
cropper.js 通過canvas實現圖片裁剪,最后在通過canvas獲取裁剪區域的圖片base64串。
cropper 文檔:官方文檔是全英文的,好吧我看不懂。只能一個個試試效果,就有了下面的總結。官方文檔<-點這
1.container 容器 2.canvas 圖片 3.crop 裁剪框
option相關參數說明:
viewMode 顯示模式
- Type:
Number
- Default:
0
- Options:
0
: the crop box is just within the container 裁剪框只能在 1內移動1
: the crop box should be within the canvas 裁剪框 只能在 2圖片內移動2
: the canvas should not be within the container 2圖片 不全部鋪滿1 (即縮小時可以有一邊出現空隙)3
: the container should be within the canvas 2圖片 全部鋪滿1 (即 再怎么縮小也不會出現空隙)
dragMode 拖動模式
- Default:
'crop'
- Options:
'crop'
: create a new crop box 當鼠標 點擊一處時根據這個點重新生成一個 裁剪框'move'
: move the canvas 可以拖動圖片'none'
: do nothing 圖片就不能拖動了
Define the dragging mode of the cropper.
toggleDragModeOnDblclick 默認true .是否允許 拖動模式 “crop” 跟“move” 的切換狀態。。即當點下為crop 模式,如果未松開拖動這時就是“move”模式。放開后又為“crop”模式
preview 截圖的顯示位置 型:String
(jQuery選擇器),默認值''
responsive :類型:Boolean
,默認值true
。是否在窗口尺寸改變的時候重置cropper。
checkImageOrigin:類型:Boolean
,默認值true
。默認情況下,插件會檢測圖片的源,如果是跨域圖片,圖片元素會被添加crossOrigin
class,並會為圖片的url添加一個時間戳來使getCroppedCanvas
變為可用。添加時間戳會使圖片重新加載,以使跨域圖片能夠使用getCroppedCanvas
。在圖片上添加crossOrigin
class會阻止在圖片url上添加時間戳,及圖片的重新加載。
Boolean
,默認值
true
。是否在容器上顯示網格背景。 要想改背景,我是直接改,cropper.css樣式中的 cropper-bg
Boolean
,默認值
true
。是否允許移動圖片
Boolean
,默認值
true
。是否允許旋轉圖片。
aspectRatio 裁剪框比例 默認NaN
例如:: 1 / 1,//裁剪框比例 1:1
autoCrop:類型:
Boolean
,默認值
true
。是否允許在初始化時自動出現裁剪框。autoCropArea:類型:
Number
,默認值
0.8
(圖片的80%)。0-1之間的數值,定義自動剪裁框的大小。highlight:類型:
Boolean
,默認值
true
。是否在剪裁框上顯示白色的模態窗口。
Boolean
,默認值
true
。是否在剪裁框上顯示虛線。
Number
,默認值
200
。容器的最小寬度。minContainerHeight:類型:
Number
,默認值
100
。容器的最小高度。minCanvasWidth:類型:
Number
,默認值
0
。canvas 的最小寬度(image wrapper)。minCanvasHeight:類型:
Number
,默認值
0
。canvas 的最小高度(image wrapper)。監聽觸發的方法build:類型:
Function
,默認值
null
。
build.cropper
事件的簡寫方式。 ====== 。控件初始化前執行built:類型:
Function
,默認值
null
。
built.cropper
事件的簡寫方式。 ====== 空間初始化完成后執行dragstart:類型:
Function
,默認值
null
。
dragstart.cropper
事件的簡寫方式。 ====== 拖動開始執行dragmove:類型:
Function
,默認值
null
。
dragmove.cropper
事件的簡寫方式。====== 拖動移動中執行dragend:類型:
Function
,默認值
null
。
dragend.cropper
事件的簡寫方式。====== 拖動結束執行zoomin:類型:
Function
,默認值
null
。
zoomin.cropper
事件的簡寫方式。 ====== 縮小執行zoomout:類型:
Function
,默認值
null
。
zoomout.cropper
事件的簡寫方式。 ====== 放大執行
html
- <section style="margin-top: 50px;">
- <input id="photoBtn" type="button" onclick="document.getElementById('inputImage').click()" value="選擇照片"><!-- 可以增加自己的樣式 -->
- <input id="inputImage" type="file" accept="image/*" style="display: none;"/>
- <br/>
- <img id="showImg" />
- </section>
- <div class="container" style="padding: 0;margin: 0;position:fixed;display: none;top: 0;left: 0;z-index: 200;" id="containerDiv">
- <div class="row" style="display: none;" id="imgEdit">
- <div class="col-md-9">
- <div class="img-container">
- <img src="" alt="Picture">
- </div>
- </div>
- </div>
- <div class="row" id="actions" style="padding: 0;margin: 0;width: 100%;position: fixed;bottom: 5px;">
- <div class="col-md-9 docs-buttons">
- <div class="btn-group" >
- <button type="button" class="btn btn-primary" data-method="destroy" title="Destroy" style="height: auto;">
- <span class="docs-tooltip" data-toggle="tooltip" >
- <span class="fa fa-power-off" >取消</span>
- </span>
- </button>
- </div>
- <div class="btn-group btn-group-crop " style="float: right;">
- <button type="button" class="btn btn-primary" id="imgCutConfirm" data-method="getCroppedCanvas" data-option="{ "width": 320, "height": 180 }" style="height: auto;margin-right: 17px;">
- <span class="docs-tooltip" data-toggle="tooltip" title="">確認</span> <!--cropper.getCroppedCanvas({ width: 320, height: 180 }) -->
- </button>
- </div>
- </div><!-- /.docs-buttons -->
- </div>
- </div>
- </pre><pre name="code" class="html">
使用調用cropper 截圖 的js
- var fileImg = "";
- </pre><pre name="code" class="html">window.onload = function () {
- 'use strict';//表示強規則
- var screenWidth = $(window).width();
- var screenHeight = $(window).height();
- var Cropper = window.Cropper;
- var console = window.console || { log: function () {} };
- var container = document.querySelector('.img-container');
- var image = container.getElementsByTagName('img').item(0);
- var actions = document.getElementById('actions');
- var isUndefined = function (obj) {
- return typeof obj === 'undefined';
- };
- var options = {
- minContainerHeight : screenHeight,
- minContainerWidth : screenWidth,
- aspectRatio: 1 / 1,//裁剪框比例 1:1
- viewMode : 1,//顯示
- guides :false,//裁剪框虛線 默認true有
- dragMode : "move",
- build: function (e) { //加載開始
- //可以放你的過渡 效果
- },
- built: function (e) { //加載完成
- $("#containerDiv").show();
- $("#imgEdit").show();
- },
- zoom: function (e) {
- console.log(e.type, e.detail.ratio);
- },
- background : true,// 容器是否顯示網格背景
- movable : true,//是否能移動圖片
- cropBoxMovable :false,//是否允許拖動裁剪框
- cropBoxResizable :false,//是否允許拖動 改變裁剪框大小
- };
- var cropper = new Cropper(image, options);
- //禁用默認方法
- function preventDefault(e) {
- if (e) {
- if (e.preventDefault) {
- e.preventDefault();
- } else {
- e.returnValue = false;
- }
- }
- }
- // Tooltip
- $('[data-toggle="tooltip"]').tooltip();
- if (typeof document.createElement('cropper').style.transition === 'undefined') {
- $('button[data-method="rotate"]').prop('disabled', true);
- $('button[data-method="scale"]').prop('disabled', true);
- }
- // Methods
- actions.querySelector('.docs-buttons').onclick = function (event) {
- var e = event || window.event;
- var target = e.target || e.srcElement;
- var result;
- var input;
- var data;
- if (!cropper) {
- return;
- }
- while (target !== this) {
- if (target.getAttribute('data-method')) {
- break;
- }
- target = target.parentNode;
- }
- if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
- return;
- }
- data = {
- method: target.getAttribute('data-method'),
- target: target.getAttribute('data-target'),
- option: target.getAttribute('data-option'),
- secondOption: target.getAttribute('data-second-option')
- };
- if (data.method) {
- if (typeof data.target !== 'undefined') {
- input = document.querySelector(data.target);
- if (!target.hasAttribute('data-option') && data.target && input) {
- try {
- data.option = JSON.parse(input.value);
- } catch (e) {
- console.log(e.message);
- }
- }
- }
- if (data.method === 'getCroppedCanvas') {
- data.option = JSON.parse(data.option);
- }
- result = cropper[data.method](data.option, data.secondOption);
- switch (data.method) {
- case 'scaleX':
- case 'scaleY':
- target.setAttribute('data-option', -data.option);
- break;
- case 'getCroppedCanvas':
- if (result) {
- fileImg = result.toDataURL('image/jpg');
- $("#showImg").attr("src",fileImg).show();
- $("#photoBtn").val("重新選擇");
- }
- break;
- case 'destroy':
- $("#inputImage").val("");
- $("#containerDiv").hide();
- $("#imgEdit").hide();
- break;
- }
- if (typeof result === 'object' && result !== cropper && input) {
- try {
- input.value = JSON.stringify(result);
- } catch (e) {
- console.log(e.message);
- }
- }
- }
- };
- // Import image
- var inputImage = document.getElementById('inputImage');
- var URL = window.URL || window.webkitURL;
- var blobURL;
- if (URL) {
- inputImage.onchange = function () {
- var files = this.files;
- var file;
- if (cropper && files && files.length) {
- file = files[0];
- if (/^image\/\w+/.test(file.type)) {
- blobURL = URL.createObjectURL(file);
- cropper.reset().replace(blobURL);
- } else {
- window.alert('Please choose an image file.');
- }
- }
- $(inputImage).find("img").hide();
- };
- } else {
- inputImage.disabled = true;
- inputImage.parentNode.className += ' disabled';
- }
- };
- $("#imgCutConfirm").bind("click",function(){
- <span style="white-space:pre"> </span>$("#containerDiv").hide();
- <span style="white-space:pre"> </span>$("#imgEdit").hide();
- <span style="white-space:pre"> </span>$("#getCroppedCanvasModal").modal("hide");
- })
獲取截圖 並ajax提交,
- //提交表達
- function submitForm(){
- $("#registerForm").attr("enctype","multipart/form-data");
- var formData = new FormData($("#registerForm")[0]);
- formData.append("imgBase64",encodeURIComponent(fileImg));//
- formData.append("fileFileName","photo.jpg");
- $.ajax({
- url: "",
- type: 'POST',
- data: formData,
- timeout : 10000, //超時時間設置,單位毫秒
- async: true,
- cache: false,
- contentType: false,
- processData: false,
- success: function (result) {
- },
- error: function (returndata) {
- }
- });
- }
使用canvas生成的截圖。我只找到生成base64的。就是那一長串字符。。
原本我想生成jpg / png ,,沒找到。
后來找到在后台 把base64 的轉成jpg/png 的方法。
然后又把圖片上傳到七牛上面,發現可以使用二進制流上傳,就不用jpg了
后台處理base64 java代碼片段
- /**
- * 上傳base64
- * @param imgBase64 圖片base64
- * @param fileName 圖片名稱
- * @return
- */
- private String uploadImgBase64(String imgBase64,String fileName){
- String uploadPath=FILEDATE;
- String fileExt = fileFileName.substring(fileFileName.lastIndexOf(".") + 1).toLowerCase();//上傳的文件的后綴
- String newFileName = fileName+ "." + fileExt;//上傳后的文件名字
- String uploadPathName = uploadPath + newFileName;//獲取到上傳后的文件路徑+文件名
- BASE64Decoder decoder = new BASE64Decoder();
- imgBase64 = imgBase64.substring(30);
- try {
- imgBase64 = URLDecoder.decode(imgBase64,"UTF-8");
- byte[] decodedBytes = decoder.decodeBuffer(imgBase64);// 將字符串格式的imagedata轉為二進制流(biye[])的decodedBytes
- for(int i=0;i<decodedBytes.length;++i){
- if(decodedBytes[i]<0) {
- //調整異常數據
- decodedBytes[i]+=256;
- }
- }
- //使用七牛上傳
- new QiniuUploadFile().upload(decodedBytes, uploadPathName);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return uploadPathName;
- }
我參考的文章咻咻咻
1.jQuery簡單且功能強大的圖片剪裁插件
2.英文copper api 當找不到方法時,可以看這里,不要怕英文版的,實在不行你可以一個一個試過去看看效果哈哈。不會告訴你我就是這么干的。