最近有个项目要在浏览器端裁剪并上传图片。由于缺乏人力,只能我上阵杀敌。通过参考各种文章,最后决定用cropperjs进行图片裁剪,用webuploader上传文件。本文涉及到的知识至少有Java基础、SpringMVC、thymeleaf模版引擎、JS基础、JQuery基础、Bootstrap组件,但是文章重点只是cropperjs和webuploader的组合运用,其他的都是辅助。

1. 依赖JS库

webuploader官网

cropperjs演示主页

cropperjs开源主页

2. 核心流程

  • 2.1 选择文件按钮

previewImg用于预览上传后的图片;picker用于选择图片,webuploader会自动给picker赋予选择文件的特性。fileInput用于接收文件数据。

  1. <div class="form-group">
  2. <img id="previewImg" width="200px" />
  3. <div>
  4. <a href="javascript:void(0)" id="picker">选择图片</a>
  5. <input type="file" id="fileInput" style="display: none" />
  6. </div>
  7. </div>

下面代码给fileInput组件触发了点击事件

  1. $("#picker").on('click', function () {
  2. $("#fileInput").trigger("click");
  3. });
  • 2.2 定义组件参数和事件

以下代码定义上传组件对象

  1. var uploader = WebUploader.create({
  2. auto: true,// 选完文件后,是否自动上传。
  3. server: '/upload',
  4. fileSingleSizeLimit: 2 * 1024 * 1024,
  5. duplicate: true,
  6. accept: {// 只允许选择图片文件。
  7. title: 'Images',
  8. extensions: 'jpg,jpeg,png',
  9. mimeTypes: 'image/jpg,image/jpeg,image/png'
  10. },
  11. //如果有表单数据要上传,可以给formData赋值
  12. formData: {
  13. id: 0
  14. }
  15. });

以下代码定义上传组件事件。WebUploader组件不提供UI,如果需要定制界面,实现下面的方法即可。

  1. //提交额外的表单数据
  2. uploader.on('uploadBeforeSend', function (object, data, header) {
  3. data.id = $('#id').val();
  4. });
  5. // 当有文件被添加进队列的时候
  6. uploader.on('fileQueued', function (file) {
  7. $('#file_list').append('<div id="' + file.id + '" class="item">' +
  8. '<h4 class="info">' + file.name + '</h4>' +
  9. '<p class="state">等待上传...</p>' +
  10. '</div>');
  11. });
  12. // 上传成功
  13. uploader.on('uploadSuccess', function (file, response) {
  14. $('#' + file.id).find('p.state').text('已上传');
  15. console.log(response._raw);
  16. var object = $.parseJSON(response._raw);
  17. //给预览组件赋值
  18. $('#previewImg').attr("src", object.url);
  19. });
  20. // 上传发生错误
  21. uploader.on('uploadError', function (file) {
  22. $('#' + file.id).find('p.state').text('上传出错');
  23. });
  24. // 上传中
  25. uploader.on('startUpload', function (file, rs) {
  26. console.log("文件正在上传中,请稍候");
  27. });
  • 2.3 定义裁剪组件参数和事件

以下代码定义裁剪图片的对话框,cropperImage是上传后的图片,被裁剪的目标对象。

  1. <div class="modal" id="cropperImageModal" tabindex="-1" role="dialog" aria-labelledby="cropperImageModal"
  2. aria-hidden="true">
  3. <div class="modal-dialog" style="width: 50%;">
  4. <div class="modal-content">
  5. <div class="modal-header">
  6. <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
  7. <h4 class="modal-title">裁剪图片</h4>
  8. </div>
  9. <div class="modal-body">
  10. <!-- cropperImage是上传后的图片,被裁剪的目标对象 -->
  11. <img src="" id="cropperImage" style="max-width: 100%"/>
  12. </div>
  13. <div class="modal-footer">
  14. <button type="button" class="btn btn-default" data-dismiss="modal" id="modalClose">关闭</button>
  15. <button type="button" class="btn btn-primary" id="modalSubmit">保存</button>
  16. </div>
  17. </div>
  18. </div>
  19. </div>

以下代码定义图片裁剪参数,更多参数参考cropper.js的API详解。如果不需要固定裁剪区域大小,删除ready函数即可。

  1. var cropperImage = $("#cropperImage");
  2. var cropperOptions = {
  3. viewMode: 1,
  4. dragMode: 'none',
  5. aspectRatio: 1,
  6. background: false,
  7. autoCropArea: 0.6,
  8. crop: function (event) {
  9. //裁剪的实时事件
  10. console.log(event.detail.width);
  11. console.log(event.detail.height);
  12. },
  13. ready: function () {
  14. //限定裁剪区域大小为500
  15. cropperImage.cropper('crop');
  16. cropperImage.cropper('setData', {
  17. width: 500,
  18. height: 500
  19. })
  20. }
  21. };
  • 2.5 触发裁剪和上传事件

fileInput组件的change事件会采用FileReader对象获得上传的Image,初始化cropperjs裁剪方法。

  1. $("#fileInput").on('change', function () {
  2. var file = this.files[0];
  3. //定义读文件对象
  4. var reader = new FileReader();
  5. reader.onload = function () {
  6. imageOnload(reader.result);
  7. };
  8. reader.readAsDataURL(file);//File对象转换为dataURL
  9. });
  10. //图片对象加载方法
  11. function imageOnload(url) {
  12. var cropperImg = new Image();
  13. cropperImg.src = url;
  14. //destroy方法是为了重入不出错
  15. cropperImage.cropper('destroy').attr('src', url).cropper(cropperOptions);
  16. cropperImg.onload = function () {
  17. //弹窗裁剪
  18. $('#cropperImageModal').modal();
  19. $("#modalClose").on('click', function () {
  20. $("#fileInput").val('');
  21. $('#cropperImageModal').modal('hide');
  22. });
  23. $("#modalSubmit").on('click', function () {
  24. var canVas = $("#cropperImage").cropper("getCroppedCanvas", {});//获取裁剪后得到的canvas数据
  25. var file = convertBase64UrlToBlob(canVas.toDataURL('image/jpeg', '0.0'));//将canvas转换为Blob格式
  26. uploader.addFiles(file);//将裁剪后的图片添加进webuploader上传到后台
  27. $('#cropperImageModal').modal('hide');
  28. $("#fileInput").val('');
  29. });
  30. };
  31. }

采用cropperImage.cropper('getCroppedCanvas').toblob(function(blob){})也可以获取图片二进制对象,但是默认是png格式,体积很大,不利于网络传输,采用下面的方法可以指定图片格式。

  1. /**
  2. * base64转为blob,图片为jpeg格式
  3. */
  4. function convertBase64UrlToBlob(urlData) {
  5. //去掉url的头,并转换为byte
  6. var bytes = window.atob(urlData.split(',')[1]);
  7. //处理异常,将ascii码小于0的转换为大于0
  8. var ab = new ArrayBuffer(bytes.length);
  9. var ia = new Uint8Array(ab);
  10. for (var i = 0; i < bytes.length; i++) {
  11. ia[i] = bytes.charCodeAt(i);
  12. }
  13. return new Blob([ab], {type: 'image/jpeg'});
  14. }
  • 2.6 后端接口实现

  1. @Controller
  2. public class IndexController {
  3. protected final Logger logger = LoggerFactory.getLogger(getClass());
  4. @RequestMapping("/index")
  5. public String list(ModelMap map) {
  6. return "index";
  7. }
  8. @PostMapping("/upload")
  9. @ResponseBody
  10. public UploadFileVo uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("id") Integer id, HttpServletResponse response) {
  11. response.setContentType("text/html");
  12. //保存图片到服务端,返回访问地址
  13. UploadFileVo uploadFileVo = new UploadFileVo();
  14. //这里为了演示,返回一张网图
  15. uploadFileVo.setUrl("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png");
  16. logger.info("上传成功,url:{},id:{}", uploadFileVo.getUrl(), id);
  17. return uploadFileVo;
  18. }
  19. }
  • 2.7 最终效果图

3. 完整代码

查阅演示代码

参考

https://www.codingbrick.com/archives/456.html

演示webuploader和cropperjs图片裁剪上传的更多相关文章

  1. PHP+jQuery.photoClip.js支持手势的图片裁剪上传实例

    PHP+jQuery.photoClip.js支持手势的图片裁剪上传实例,在手机上双指捏合为缩放,双指旋转可根据旋转方向每次旋转90度,在电脑上鼠标滚轮为缩放,双击则顺时针旋转90度. 下面让我们来看 ...

  2. vue中使用cropperjs进行图片裁剪上传

    下面代码直接就可以复制使用了,但是需要在本地下个cropperjs,下载命令:npm install cropperjs --save-dev <template> <div id= ...

  3. 微信小程序实现图片裁剪上传(wepy)

    参考https://github.com/we-plugin/we-cropper,在wepy中实现,参考的具体例子是we-cropper/example/cutInside/ 项目上传图片时2:3的 ...

  4. 图片裁剪上传插件——jquery.photoClip.js

    想要裁剪图片上传: 需要依赖的的插件为: [jquery.photoClip.js] 插件[iscroll-zoom.js] 插件[hammer.js] 插件 [lrz.all.bundle.js] ...

  5. PHP裁剪图片并上传完整demo

    日前根据功能需求,要做一个图片裁剪上传的功能,在网上找了好久,找到了这位仁兄写的demo! 下载压缩包

  6. 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)

    涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...

  7. PHP 多图上传,图片批量上传插件,webuploader.js,百度文件上传插件

    PHP  多图上传,图片批量上传插件,webuploader.js,百度文件上传插件(案例教程) WebUploader作用:http://fex.baidu.com/webuploader/gett ...

  8. asp.net实现图片在线上传并在线裁剪

    1.说明 接上一篇文章uploadify实现多附件上传完成后,又突然用到头像上传并在线裁剪.在网上找个众多例子都没有符合要求的,有一篇文章写的不错,就是文旺老兄写的这篇Asp.Net平台下的图片在线裁 ...

  9. HTML5 本地裁剪图片并上传至服务器(转)

    很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的.但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 ...

  10. HTML5裁剪图片并上传至服务器实现原理讲解

    HTML5裁剪图片并上传至服务器实现原理讲解   经常做项目需要本地上传图片裁剪并上传服务器,比如会议头像等功能,但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁 ...

随机推荐

  1. VC-MFC(2) 随笔笔记

    1 //点击按钮出来对话框---------------- 2 3 1.首先添加 对话框(标识符) 4 2.在点击按钮出来第二个对话框,直接鼠标右键 新建 类 5 3.在.CPP添加新建类的 头文件 ...

  2. 我和我的DBA之路

    这几天,突然想写写这些年的工作总结,毕业至今快20年的回顾. 想到20年前,在做毕业设计的时候,当时是学的机械工程类专业,因为带毕业设计的老师兼职企业有个门户网站的需求,而我又会做点网站设计,带的老师 ...

  3. 跨域测试代码 - console 里面直接就可以测试

    跨域测试代码 - console 里面直接就可以测试 var xhr = new XMLHttpRequest(); xhr.open("GET", "https://w ...

  4. nvm-windows 安装遇到的问题 node目录卸载后(有残留)记得改名

    需求 网上好多新项目都需要最新版的node,所有需要切换node版本 nvm-windows https://github.com/coreybutler/nvm-windows 安装步骤-问题 删除 ...

  5. 基于ads1299的可穿戴脑电信号采集之性能调试总结

    一 前言 问题背景: 最近做项目,遇到了一个问题,就是采集的信号有噪声,在这里做了很多尝试.   二 测试步骤 A 内部方波信号质量,通过测试发现内部方波信号质量特别好.这个说明了软件和存储这块,没啥 ...

  6. day01-2-导入驱动和工具类

    满汉楼01-2 4.功能实现01 4.1导入驱动和工具类 4.1.1导入驱动 首先将连接mysql的相关jar包引入项目中,分别右键,点击add as library 4.1.2导入工具类Utilit ...

  7. github拉项目显示timeOut

    参考:https://blog.csdn.net/qq_37424778/article/details/132018804 自己尝试在github上拉项目,但是报错LibreSSL SSL_read ...

  8. java基础之字符串转日期

    package com.iamzken.utils; import java.text.ParseException; import java.text.SimpleDateFormat; impor ...

  9. 活动报名|3DCAT实时渲染云行业生态合作系列沙龙之“云XR如何赋能虚拟仿真实验教学”线上活动邀您参会

    当前,虚拟现实发展方兴未艾,"XR+教育"融合发展前景广阔. 3DCAT实时渲染云积极联动教育行业渠道商等生态合作伙伴,合力打造"虚拟现实实验室"." ...

  10. 可视化学习:实现Canvas图片局部放大镜

    前言 最近我在可视化课程中学习了如何在Canvas中利用像素处理来实现滤镜效果,在这节课程的结尾留了一道局部放大镜的题目,提示我们用像素处理的方式去实现这个效果,最终实现随着鼠标移动将图片局部放大,本 ...