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 相关文章推荐
jQuery表单获取和失去焦点输入框提示效果的实例代码
Aug 01 Javascript
JQUERY 获取IFrame中对象及获取其父窗口中对象示例
Aug 19 Javascript
jQuery获取和设置表单元素的方法
Feb 14 Javascript
有关jquery与DOM节点操作方法和属性记录
Apr 15 Javascript
JS弹出窗口插件zDialog简单用法示例
Jun 12 Javascript
javascript数组遍历的方法实例分析
Sep 13 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
Sep 21 Javascript
3种vue组件的书写形式
Nov 29 Javascript
简单谈谈CommonsChunkPlugin抽取公共模块
Dec 31 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
Oct 14 Javascript
微信小程序图片加载失败时替换为默认图片的方法
Dec 09 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
Jan 05 Vue.js
原生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 动态随机生成验证码类代码
2010/04/09 PHP
php中常用字符串处理代码片段整理
2011/11/07 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
JavaScript获取/更改文本框的值的实例代码
2013/08/02 Javascript
SeaJS入门教程系列之使用SeaJS(二)
2014/03/03 Javascript
简单的js图片轮换代码(js图片轮播)
2014/05/06 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
浅谈JavaScript中的字符编码转换问题
2015/07/07 Javascript
jQuery+ajax简单实现文件上传的方法
2016/06/03 Javascript
浅析jQuery Ajax通用js封装
2016/06/22 Javascript
Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信
2017/02/23 Javascript
JavaScript设计模式之代理模式详解
2017/06/09 Javascript
使用jquery的jsonp如何发起跨域请求及其原理详解
2017/08/17 jQuery
get  post jsonp三种数据交互形式实例详解
2017/08/25 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
判断文字超过2行添加展开按钮,未超过则不显示,溢出部分显示省略号
2019/04/28 Javascript
实用的Vue开发技巧
2019/05/30 Javascript
Vue中实现回车键切换焦点的方法
2020/02/19 Javascript
基于VSCode调试网页JavaScript代码过程详解
2020/07/20 Javascript
vant 时间选择器--开始时间和结束时间实例
2020/11/04 Javascript
[40:04]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
python实现unicode转中文及转换默认编码的方法
2017/04/29 Python
解决pycharm每次新建项目都要重新安装一些第三方库的问题
2019/01/17 Python
CentOS6.9 Python环境配置(python2.7、pip、virtualenv)
2019/05/06 Python
django 中的聚合函数,分组函数,F 查询,Q查询
2019/07/25 Python
Python filter过滤器原理及实例应用
2020/08/18 Python
意大利在线购买隐形眼镜网站:VisionDirect.it
2019/03/18 全球购物
业务员岗位职责
2013/11/16 职场文书
研究生考核个人自我鉴定
2014/03/27 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
2014年项目经理工作总结
2014/11/24 职场文书
复兴之路观后感
2015/06/02 职场文书
Mongo服务重启异常问题的处理方法
2021/07/01 MongoDB
centos8安装nginx1.9.1的详细过程
2021/08/02 Servers
为了顺利买到演唱会的票用Python制作了自动抢票的脚本
2021/10/16 Python