cropper.js 实现HTML5 裁剪图片并上传(裁剪上传头像。)

 

  我的需求功能:在手机端实现上传头像,带裁剪框。

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上添加时间戳,及图片的重新加载。

background:类型:Boolean,默认值true。是否在容器上显示网格背景。 要想改背景,我是直接改,cropper.css样式中的 cropper-bg

 

canvas(图片)相关

movable:类型:Boolean,默认值true。是否允许移动图片

rotatable:类型:Boolean,默认值true。是否允许旋转图片。

scalable  默认 true 。 是否允许扩展图片。(暂时不知道干嘛用)

zoomable 默认true, 石头允许缩放图片。

zoomOnWheel 默认 true 是否允许鼠标滚轴 缩放图片

zoomOnTouch 默认true 是否允许触摸缩放图片(触摸屏上两手指操作。)

wheelZoomRatio 默认0.1 师表滚轴缩放图片比例。即滚一下。图片缩放多少。如 0.1 就是图片的10%

 

crop(裁剪框)相关

aspectRatio 裁剪框比例  默认NaN   例如:: 1 / 1,//裁剪框比例 1:1

modal:类型:Boolean,默认值true。是否在剪裁框上显示黑色的模态窗口。

cropBoxMovable :默认true ,是否允许拖动裁剪框cropBoxResizable :默认 true,//是否允许拖动 改变裁剪框大小
autoCrop:类型:Boolean,默认值true。是否允许在初始化时自动出现裁剪框。autoCropArea:类型:Number,默认值0.8(图片的80%)。0-1之间的数值,定义自动剪裁框的大小。highlight:类型:Boolean,默认值true。是否在剪裁框上显示白色的模态窗口。

guides:类型:Boolean,默认值true。是否在剪裁框上显示虚线。

center:  默认true  是否显示裁剪框 中间的+ 

restore :  类型:Boolean,默认值true  是否调整窗口大小后恢复裁剪区域。

大小相关

minContainerWidth:类型:Number,默认值200。容器的最小宽度。minContainerHeight:类型:Number,默认值100。容器的最小高度。minCanvasWidth:类型:Number,默认值0。canvas 的最小宽度(image wrapper)。minCanvasHeight:类型:Number,默认值0。canvas 的最小高度(image wrapper)。监听触发的方法build:类型:Function,默认值nullbuild.cropper事件的简写方式。 ====== 。控件初始化前执行built:类型:Function,默认值nullbuilt.cropper事件的简写方式。  ====== 空间初始化完成后执行dragstart:类型:Function,默认值nulldragstart.cropper事件的简写方式。 ======  拖动开始执行dragmove:类型:Function,默认值nulldragmove.cropper事件的简写方式。======  拖动移动中执行dragend:类型:Function,默认值nulldragend.cropper事件的简写方式。======  拖动结束执行zoomin:类型:Function,默认值nullzoomin.cropper事件的简写方式。 ======  缩小执行zoomout:类型:Function,默认值nullzoomout.cropper事件的简写方式。 ======  放大执行

 

demo 下载   分数被调高了。

 

新下载地址点-》   demo

html  

 


 
 
  1. <section style="margin-top: 50px;">
  2. <input id="photoBtn" type="button" onclick="document.getElementById('inputImage').click()" value="选择照片"> <!-- 可以增加自己的样式 -->
  3. <input id="inputImage" type="file" accept="image/*" style="display: none;"/>
  4. <br/>
  5. <img id="showImg" />
  6. </section>
  7. <div class="container" style="padding: 0;margin: 0;position:fixed;display: none;top: 0;left: 0;z-index: 200;" id="containerDiv">
  8. <div class="row" style="display: none;" id="imgEdit">
  9. <div class="col-md-9">
  10. <div class="img-container">
  11. <img src="" alt="Picture">
  12. </div>
  13. </div>
  14. </div>
  15. <div class="row" id="actions" style="padding: 0;margin: 0;width: 100%;position: fixed;bottom: 5px;">
  16. <div class="col-md-9 docs-buttons">
  17. <div class="btn-group" >
  18. <button type="button" class="btn btn-primary" data-method="destroy" title="Destroy" style="height: auto;">
  19. <span class="docs-tooltip" data-toggle="tooltip" >
  20. <span class="fa fa-power-off" >取消 </span>
  21. </span>
  22. </button>
  23. </div>
  24. <div class="btn-group btn-group-crop " style="float: right;">
  25. <button type="button" class="btn btn-primary" id="imgCutConfirm" data-method="getCroppedCanvas" data-option="{ "width": 320, "height": 180 }" style="height: auto;margin-right: 17px;">
  26. <span class="docs-tooltip" data-toggle="tooltip" title="">确认 </span> <!--cropper.getCroppedCanvas({ width: 320, height: 180 }) -->
  27. </button>
  28. </div>
  29. </div> <!-- /.docs-buttons -->
  30. </div>
  31. </div>
</pre><pre name="code" class="html">
 
 

 

 

 使用调用cropper 截图   的js 

 

var fileImg = "";

 
 

 
 
  1. </pre> <pre name="code" class="html">window.onload = function () {
  2. 'use strict';//表示强规则
  3. var screenWidth = $(window).width();
  4. var screenHeight = $(window).height();
  5. var Cropper = window.Cropper;
  6. var console = window.console || { log: function () {} };
  7. var container = document.querySelector('.img-container');
  8. var image = container.getElementsByTagName('img').item(0);
  9. var actions = document.getElementById('actions');
  10. var isUndefined = function (obj) {
  11. return typeof obj === 'undefined';
  12. };
  13. var options = {
  14. minContainerHeight : screenHeight,
  15. minContainerWidth : screenWidth,
  16. aspectRatio: 1 / 1,//裁剪框比例 1:1
  17. viewMode : 1,//显示
  18. guides :false,//裁剪框虚线 默认true有
  19. dragMode : "move",
  20. build: function (e) { //加载开始
  21. //可以放你的过渡 效果
  22. },
  23. built: function (e) { //加载完成
  24. $("#containerDiv").show();
  25. $("#imgEdit").show();
  26. },
  27. zoom: function (e) {
  28. console.log(e.type, e.detail.ratio);
  29. },
  30. background : true,// 容器是否显示网格背景
  31. movable : true,//是否能移动图片
  32. cropBoxMovable :false,//是否允许拖动裁剪框
  33. cropBoxResizable :false,//是否允许拖动 改变裁剪框大小
  34. };
  35. var cropper = new Cropper(image, options);

 
 
  1. //禁用默认方法
  2. function preventDefault(e) {
  3. if (e) {
  4. if (e.preventDefault) {
  5. e.preventDefault();
  6. } else {
  7. e.returnValue = false;
  8. }
  9. }
  10. }
  11. // Tooltip
  12. $('[data-toggle="tooltip"]').tooltip();
  13. if (typeof document.createElement('cropper').style.transition === 'undefined') {
  14. $('button[data-method="rotate"]').prop('disabled', true);
  15. $('button[data-method="scale"]').prop('disabled', true);
  16. }
  17. // Methods
  18. actions.querySelector('.docs-buttons').onclick = function (event) {
  19. var e = event || window.event;
  20. var target = e.target || e.srcElement;
  21. var result;
  22. var input;
  23. var data;
  24. if (!cropper) {
  25. return;
  26. }
  27. while (target !== this) {
  28. if (target.getAttribute('data-method')) {
  29. break;
  30. }
  31. target = target.parentNode;
  32. }
  33. if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
  34. return;
  35. }
  36. data = {
  37. method: target.getAttribute('data-method'),
  38. target: target.getAttribute('data-target'),
  39. option: target.getAttribute('data-option'),
  40. secondOption: target.getAttribute('data-second-option')
  41. };
  42. if (data.method) {
  43. if (typeof data.target !== 'undefined') {
  44. input = document.querySelector(data.target);
  45. if (!target.hasAttribute('data-option') && data.target && input) {
  46. try {
  47. data.option = JSON.parse(input.value);
  48. } catch (e) {
  49. console.log(e.message);
  50. }
  51. }
  52. }
  53. if (data.method === 'getCroppedCanvas') {
  54. data.option = JSON.parse(data.option);
  55. }
  56. result = cropper[data.method](data.option, data.secondOption);
  57. switch (data.method) {
  58. case 'scaleX':
  59. case 'scaleY':
  60. target.setAttribute('data-option', -data.option);
  61. break;
  62. case 'getCroppedCanvas':
  63. if (result) {
  64. fileImg = result.toDataURL('image/jpg');
  65. $("#showImg").attr("src",fileImg).show();
  66. $("#photoBtn").val("重新选择");
  67. }
  68. break;
  69. case 'destroy':
  70. $("#inputImage").val("");
  71. $("#containerDiv").hide();
  72. $("#imgEdit").hide();
  73. break;
  74. }
  75. if (typeof result === 'object' && result !== cropper && input) {
  76. try {
  77. input.value = JSON.stringify(result);
  78. } catch (e) {
  79. console.log(e.message);
  80. }
  81. }
  82. }
  83. };
  84. // Import image
  85. var inputImage = document.getElementById('inputImage');
  86. var URL = window.URL || window.webkitURL;
  87. var blobURL;
  88. if (URL) {
  89. inputImage.onchange = function () {
  90. var files = this.files;
  91. var file;
  92. if (cropper && files && files.length) {
  93. file = files[0];
  94. if (/^image\/\w+/.test(file.type)) {
  95. blobURL = URL.createObjectURL(file);
  96. cropper.reset().replace(blobURL);
  97. } else {
  98. window.alert('Please choose an image file.');
  99. }
  100. }
  101. $(inputImage).find("img").hide();
  102. };
  103. } else {
  104. inputImage.disabled = true;
  105. inputImage.parentNode.className += ' disabled';
  106. }
  107. };

 
 
  1. $("#imgCutConfirm").bind("click",function(){
  2. <span style="white-space:pre"> </span>$("#containerDiv").hide();
  3.   <span style="white-space:pre"> </span>$("#imgEdit").hide();
  4. <span style="white-space:pre"> </span>$("#getCroppedCanvasModal").modal("hide");
  5. })

 

 

 

 

 

获取截图 并ajax提交,  

 


 
 
  1. //提交表达
  2. function submitForm(){
  3. $("#registerForm").attr("enctype","multipart/form-data");
  4. var formData = new FormData($("#registerForm")[0]);
  5. formData.append("imgBase64",encodeURIComponent(fileImg));//
  6. formData.append("fileFileName","photo.jpg");
  7. $.ajax({
  8. url: "",
  9. type: 'POST',
  10. data: formData,
  11. timeout : 10000, //超时时间设置,单位毫秒
  12. async: true,
  13. cache: false,
  14. contentType: false,
  15. processData: false,
  16. success: function (result) {
  17. },
  18. error: function (returndata) {
  19. }
  20. });
  21. }

 

使用canvas生成的截图。我只找到生成base64的。就是那一长串字符。。

 

原本我想生成jpg / png ,,没找到。  

后来找到在后台 把base64 的转成jpg/png  的方法。

然后又把图片上传到七牛上面,发现可以使用二进制流上传,就不用jpg了

  后台处理base64 java代码片段

 


 
 
  1. /**
  2. * 上传base64
  3. * @param imgBase64 图片base64
  4. * @param fileName 图片名称
  5. * @return
  6. */
  7. private String uploadImgBase64(String imgBase64,String fileName){
  8. String uploadPath=FILEDATE;
  9. String fileExt = fileFileName.substring(fileFileName.lastIndexOf(".") + 1).toLowerCase();//上传的文件的后缀
  10. String newFileName = fileName+ "." + fileExt;//上传后的文件名字
  11. String uploadPathName = uploadPath + newFileName;//获取到上传后的文件路径+文件名
  12. BASE64Decoder decoder = new BASE64Decoder();
  13. imgBase64 = imgBase64.substring(30);
  14. try {
  15. imgBase64 = URLDecoder.decode(imgBase64,"UTF-8");
  16. byte[] decodedBytes = decoder.decodeBuffer(imgBase64);// 将字符串格式的imagedata转为二进制流(biye[])的decodedBytes
  17. for(int i=0;i <decodedBytes.length;++i){
  18. if(decodedBytes[i]<0) {
  19. //调整异常数据
  20. decodedBytes[i]+=256;
  21. }
  22. }
  23. //使用七牛上传
  24. new QiniuUploadFile().upload(decodedBytes, uploadPathName);
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. return uploadPathName;
  29. }

===========================分割========================================

头像需要改成圆形框的方法:

cropper.js中没有提供圆形的方法,如果想要圆形的你要修改

1. cropper.js的。 在cropper.js中找到 getCroppedCanvas方法 在context.drawImage.apply上添加


 
 
  1. var circle = {
  2. x: canvasWidth / 2,
  3. y: canvasHeight / 2,
  4. r: canvasWidth / 2
  5. };
  6. context.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2, false);
  7. context.clip();

2.在cropper.css 中 这改之后就只会生成 圆形图了


 
 
  1. .cropper-face 添加border-radius: 100%;
  2. .cropper-view-box 删除outline outline-color 添加border: 2px solid #39f;
  3. border-color: rgba(51, 153, 255, .75);
  4. border-radius: 100%;

 

这改之后就只会生成 圆形图了,,具体想灵活的自由切换圆形跟矩形,就要进一步封装。

 

 

 

我参考的文章咻咻咻

 

1.jQuery简单且功能强大的图片剪裁插件          

2.英文copper  api 当找不到方法时,可以看这里,不要怕英文版的,实在不行你可以一个一个试过去看看效果哈哈。不会告诉你我就是这么干的。

 

 

3.HTML5 本地裁剪图片并上传至服务器(老梗)

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值