node.js(express)中使用Jcrop进行图片剪切上传功能


Posted in Javascript onApril 21, 2017

需求说明

简单来说就是要实现用户上传头像,并且要保存用户裁切后的部分作为用户头像。

第一步,选择图片:

node.js(express)中使用Jcrop进行图片剪切上传功能 

第二步,在弹窗页面中展现并进行裁切:

node.js(express)中使用Jcrop进行图片剪切上传功能 

第三步,点击“保存”,上传服务器。

实现过程

说来有点坎坷,相当于做了2遍,走了弯路。

第1遍是用户一选择图片,就进行了上传,然后返回一个地址,所以在弹层上展现的图片已经是服务器上的图片了,然后进行裁切,再保存。

第2遍找到的一个方法,是在第1遍做到裁切处理时候想到的,即弹层展现的是用户机器上选择的图片,不用先上传,但是用image/base64来展现的。这样就与服务器少了一次交互啊,并且服务器不用存储2遍图片,还提高了弹层展现速度,体验更好,所以是极好的。

说下碰到的主要技术点:

express框架不用多说,就是保存的时候post一下裁切后的base64数据,后台写个对应路由就好。
Jquery也不用多说,页面展现控制与ajax提交。

HTML5/FileReader/canvas,FileReader用于将文件读取为数据,我们使用它的onLoad事件;canvas这个用作裁切移动时,实时重绘裁切后的图片(相当于实时预览,当然我是隐藏了,调试的时候可以让他display),可以隐藏,最后上传的其实就是这个canvas的base64数据。

Jcrop plugin。这个是裁切插件,必须的了。下载与说明在这里。
其他就是base64字符串保存成图片了,这在服务端比较简单,直接用fs.writeFile(fileName,dataBuffer,function(err){});就好了。

具体代码

view页面,主要需要有一个上传控件,还有定义弹窗div以及用于重绘裁切范围图片的canvas,当然页面要引用相应的js插件和css等,主要:

<link rel="stylesheet" href="/css/jquery.Jcrop.css" rel="external nofollow" >
<script src="/js/jquery.js"></script>
<script src="/js/jquery.Jcrop.js"></script>
<!--上传控件-->
<input type="file" name="upLoadImg1" id="upLoadImg1">
<!--弹窗与裁切图-->
<div class="cover">
 <img id="Img1" alt="">
 <button id="btnSave">保存</button>
</div>
<!--裁切范围重绘canvas-->
<canvas id="myCanva" width="200" height="200">

js/jQuery,处理图片加载与裁切上传。

首先要监控上传控件的变化,因为我们这里没有按钮来触发,所以直接监控upLoadImg1的change来触发。

$('#upLoadImg1').on('change', function() {
 if (document.getElementById("upLoadImg1").files.length === 0) {
  return;
 }
 var oFile = document.getElementById("upLoadImg1").files[0];
 if (!oFile) {
  return;
 }
 var fileName = oFile.name;
 var fileSize = oFile.size;
 var fileType = fileName.substring(fileName.lastIndexOf('.'), fileName.length).toLowerCase();
 if (fileType != '.jpg' && fileType != '.jpeg' && fileType != '.gif' && fileType != '.png' && fileType != '.bmp') {
  alert("请选择jpg,png,gif,bmp格式的图片");
  return;
 }
 if (fileSize > 2 * 1024 * 1024) {
  alert('最大支持2MB的图片');
  return;
 }
 var fileReader = new FileReader();
 fileReader.readAsDataURL(oFile);
 // 成功读取
 fileReader.onload = function(e) {
  // 显示弹窗
  $('.cover').show();
  // 将弹窗中的图片路径设置为选择的图片的base64
  $('#Img1').attr('src', e.target.result);
  // 裁切组件初始化
  initJcrop();
 };
});

裁切在弹窗一显示的时候就应该初始化:

function initJcrop() {
 $('#Img1').Jcrop({
  onChange: updateCoords,
  onSelect: updateCoords,
  aspectRatio: 1,
  boxWidth: 300,
  boxHeight: 300
 }, function() {
  //弹窗中显示的图片尺寸 
  var bb = this.getBounds();
  var bWidth = Number(bb[0]) / 2;
  var bHeight = Number(bb[1]) / 2;
  //设置初始选中裁切范围
  this.setSelect([0, 0, bWidth, bHeight]);
  //原始图片缩小比例
  try {
   wdthScale = $('#Img1')["0"].width / 222;
   heightScale = $('#Img1')["0"].height / 238;
  } catch (e) {}
  jcrop_api = this;
 });
}

非常重要的一个坑是,在此之前要定义全局变量jcrop_api,widthScale和heightScale,2个scale变量用于记录选择的原始图片尺寸与在弹窗上展现尺寸的缩小/放大比例的,比如选择的是1024x768的图片,但是弹窗上展现的范围是222x238,这就需要将缩小的倍数记录下来,在裁切的重绘canvas的时候要乘以这个倍数,否则裁切的范围就是在这个222x236尺寸上裁切的,而不是原始图片的尺寸上裁切的。而前面的jcrop_api变量用于重新选择图片时要将上一次的裁切初始化组件destroy掉。

Jcrop组件中重要的事件:onChange和onSelect,用于确定裁切范围的坐标(尺寸),因此也非常重要,其实重绘canvas就是在这里面完成的。

function updateCoords(c) {
 var img = document.getElementById('Img1');
 var ctx = document.getElementById('myCanva').getContext('2d');
 try {
  wdthScale = wdthScale === 1 ? $('#Img1')["0"].width / 222 : wdthScale;
  heightScale = heightScale === 1 ? $('#Img1')["0"].height / 238 : heightScale;
 } catch (e) { }

 //绘制canvas画布
 ctx.drawImage(img, c.x, c.y, c.w * wdthScale, c.h * heightScale, 0, 0, 200, 200);
}

另外就是处理保存按钮来,一个ajax来提交canvas形成的图片的base64字符串,后台接受保存就可以了。

var data = document.getElementById('myCanva').toDataURL();
 $.ajax({
  url: '/xxxx',
  type: 'POST',
  dataType: 'JSON',
  cache: false,
  data: {
   'imgData': data
  },
  success: function(res) {},
  error: function(err) {}
 });

这就是上传裁切(实时预览)的全部过程了。

以上所述是小编给大家介绍的node.js(express)中使用Jcrop进行图片剪切上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js 在定义的时候立即执行的函数表达式(function)写法
Jan 16 Javascript
ie8本地图片上传预览示例代码
Jan 12 Javascript
javascritp添加url参数将参数加入到url中
Sep 25 Javascript
jquery $(document).ready()和window.onload的区别浅析
Feb 04 Javascript
浅析javascript中函数声明和函数表达式的区别
Feb 15 Javascript
BOM系列第一篇之定时器setTimeout和setInterval
Aug 17 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
Apr 17 Javascript
微信小程序实现顶部普通选项卡效果(非swiper)
Jun 19 Javascript
解决vue2.0路由跳转未匹配相应用路由避免出现空白页面的问题
Aug 24 Javascript
H5+C3+JS实现五子棋游戏(AI篇)
May 28 Javascript
详解基于electron制作一个node压缩图片的桌面应用
Jan 29 Javascript
JavaScript组合继承详解
Nov 07 Javascript
原生javascript实现分页效果
Apr 21 #Javascript
微信小程序 跳转方式总结
Apr 20 #Javascript
微信小程序 setData的使用方法详解
Apr 20 #Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
Apr 20 #Javascript
微信小程序中form 表单提交和取值实例详解
Apr 20 #Javascript
ES6新特性一: let和const命令详解
Apr 20 #Javascript
javascript 正则表达式分组、断言详解
Apr 20 #Javascript
You might like
PHP读写文件的方法(生成HTML)
2006/11/27 PHP
浅谈Eclipse PDT调试PHP程序
2014/06/09 PHP
用 Composer构建自己的 PHP 框架之基础准备
2014/10/30 PHP
PHP 开发者该知道的 5 个 Composer 小技巧
2016/02/03 PHP
php连接oracle数据库的核心步骤
2016/05/26 PHP
php版微信自定义回复功能示例
2016/12/05 PHP
PHP连接sftp并下载文件的方法教程
2018/08/26 PHP
php实现数组中出现次数超过一半的数字的统计方法
2018/10/14 PHP
JS刷新当前页面的几种方法总结
2013/12/24 Javascript
js实现页面跳转的五种方法推荐
2016/03/10 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
jQuery使用$.each遍历json数组的简单实现方法
2016/04/18 Javascript
JavaScript中用let语句声明作用域的用法讲解
2016/05/20 Javascript
好好了解一下Cookie(强烈推荐)
2016/06/14 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
2016/12/26 Javascript
jQuery实现导航回弹效果
2017/02/27 Javascript
使用重写url机制实现验证码换一张功能
2017/08/01 Javascript
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
2018/04/19 Javascript
JS实现的缓冲运动效果示例
2018/04/30 Javascript
详解小程序用户登录状态检查与更新实例
2019/05/15 Javascript
一文搞懂ES6中的Map和Set
2019/05/20 Javascript
js实现列表按字母排序
2020/08/11 Javascript
带你了解python装饰器
2017/06/15 Python
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
Python基于socket模块实现UDP通信功能示例
2018/04/10 Python
python的格式化输出(format,%)实例详解
2018/06/01 Python
Python浮点数四舍五入问题的分析与解决方法
2019/11/19 Python
Book Depository澳大利亚:世界领先的专业在线书店之一
2018/12/27 全球购物
Paradox London官方网站:英国新娘鞋婚礼鞋品牌
2019/08/29 全球购物
硕士生找工作求职信
2014/07/05 职场文书
2014年乡镇工会工作总结
2014/12/02 职场文书
高校自主招生教师推荐信
2015/03/23 职场文书
医院财务人员岗位职责
2015/04/14 职场文书
防暑降温通知书
2015/04/27 职场文书
2019年教师节祝福语精选,给老师送上真诚的祝福
2019/09/09 职场文书
Nginx 负载均衡是什么以及该如何配置
2021/03/31 Servers