需求描述
简单来说,就是用户需要上传自己的头像,把剪下来的部分保存为自己的头像。
第一步,选择一张图片:
其次,在弹出的页面中显示和剪切:
第三步,点击“保存”,上传到服务器。
实施程序
有点颠簸,相当于做了两次,走了弯路。
第一遍,用户一选择就上传图像,然后返回地址,这样弹性层显示的图像就已经是服务器上的图像了,然后剪切保存。
第二遍找到的一个方法,在第一遍做裁剪的时候就想到了,就是弹性层显示用户机器选择的图像,不需要先上传,用image/base64显示。这样与服务器的交互少了一个,服务器也不需要存储图片两次,也提高了子弹层的显示速度,体验更好,所以很优秀。
说出遇到的主要技术要点:
不用说,express框架就是在保存的时候把裁剪好的base64数据贴出来,在后台写一个对应的路由。不用说,Jquery、页面呈现控制和ajax提交。
HTML5/FileReader/canvas,FileReader用于将文件作为数据读取,我们使用它的onLoad事件;使用canvas进行剪切和移动时,可以通过实时重绘剪切后的图片来隐藏(相当于实时预览,当然我是隐藏的,让调试时显示),最后上传的数据其实就是这个canvas的base64数据。
Jcrop插件.这是一个切割插件,这是必须的。下载和说明在这里。另一种是base64字符串保存为图片,在服务器端比较简单,直接使用fs.writefile (filename,data buffer,function(err){ };没问题。
绝对代码
视图页面主要需要有一个上传控件,以及一个定义弹出窗口的div和一个重绘剪切范围图片的画布。当然,页面应该参考相应的js插件和css等。主要是:
link rel='样式表' href='/css/jquery。jcrop . CSS ' rel=' external no follow '脚本src=' http :/js/jquery . js '/script script src=' http :/js/jquery。jcrop . js '/脚本!-上传控件-输入类型=' file ' name=' uploadimg 1 ' id=' uploadimg 1 '!-弹出窗口和剪切图-div class=' cover ' img id=' img 1 ' alt=' button id=' BTN save ' save/button/div!-在剪切范围内重绘画布-画布id=' mycanva ' width=' 200 ' height=' 200 ' js/jquery,处理图片的加载和上传。
首先要监控上传控件的变化,因为这里没有按钮触发,所以可以直接监控upLoadImg1的变化来触发。
$('#upLoadImg1 ')。on('change ',function(){ if(document . getelementbyid(' uploadimg 1 '). files . length===0){ return;} var oFile=document . getelementbyid(' uploadimg 1 ')。文件[0];if(!oFile){ return;} var fileName=oFile.namevar fileSize=oFile.sizevar file type=filename . substring(filename . last indexof(' . ')),fileName.length)。toLowerCase();if (fileType!='.jpg' fileType!='.jpeg' fileType!='.' gif' fileType!='.png' fileType!='.bmp') {alert('请选择jpg、png、gif和bmp格式的图片');返回;} if (fileSize 2 * 1024 * 1024) {alert('最大支持2MB图片');返回;} var FileReader=new FileReader();file reader . readasdataurl(oFile);//成功读取file reader . onload=function(e){//显示弹出窗口$(')。封面’)。show();//将弹出窗口中的图片路径设置为base64 $ ('# img1 ')。所选图片的attr ('src ',e . target . result);//Cutting组件初始化initJcrop();};});弹出窗口一显示,修剪就应初始化:
函数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 BH aThEr=Number(bb[1])/2;//将初始选择的切削范围设置为this.setselect ([0,0,bwidth,BH八字]);//原始图片缩小比例尝试{wdthscale=$ ('# img1') ['0']。宽度/222;heightScale=$('#Img1')['0']。身高/238;} catch(e){ } jcrop _ API=this;});}一个非常重要的坑是在此之前定义全局变量jcrop_api、widthScale和heightScale。两个比例变量用于记录所选原始图片尺寸和弹出窗口上显示尺寸的缩小/放大比例。例如,所选图片为1024x768,但弹出窗口上显示的范围为222x238,因此需要记录缩小比例。裁剪时重绘画布时乘以这个倍数,否则裁剪范围会被裁剪成222x236的大小,而不是原图片的大小。而之前的jcrop_api变量用于在重新选择图片时销毁最后一个修剪初始化组件。
Jcrop组件中的重要事件,onChange和onSelect,用于确定切割范围的坐标(大小),因此它们也非常重要。事实上,重绘画布是在这里完成的。
函数updateCoords(c){ var img=document . getelementbyid(' Img1 ');var CTX=document . getelementbyid(' myCanva ')。getContext(' 2d ');尝试{ wdthScale=wdthScale===1?$('#Img1')['0']。宽度222/: wdthScale;heightScale=heightScale===1?$('#Img1')['0']。高度238/: heightScale;} catch (e) {} //绘制画布CTX.drawimage (img,c.x,c.y,c.w * wdth比例尺,c.h *高度比例尺,0,0,200,200);}另一种是处理save按钮,一个ajax提交由canvas形成的base64字符串的图片,然后在后台接受保存。
var data=document . getelementbyid(' myCanva ')。todaytaurl();$.ajax({ url: '/xxxx ',type: 'POST ',dataType: 'JSON ',cache: false,data: { 'imgData': data },success: function(res) {},error : function(err){ });这是上传裁剪的全过程(实时预览)。
以上是边肖介绍的node.js(express)中的图片剪切上传功能。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!