首页 > 代码库 > 头像上传二三事

头像上传二三事

     之前注册功能还留了一个小尾巴:完善图像上传功能。之前只是简单的input上传,没有图片做任何处理。

     以下说的就是如何将图片进行裁剪得到需要的尺寸并上传。(参考文献:http://www.open-open.com/lib/view/open1464825507226.html)

     并将这些功能进行了简单的封装 (https://github.com/zhangdongming1989/upload_helper)

1.图片DataUri

   看到这个需求不由得想到了之前看到的dataUri。dataUri实际上就是一个规定格式字符串。这个字符串实际就是是用base64编码后的图片数据。

比如这就是一个datauri图片

data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge 8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1h LnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g 77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7

把这一段粘贴到浏览器地址栏就会出现一张小图片。

这样做的好处是可以直接把datauri加到css或者html中,而不用再单独传一个图片——减少http请求。但是也有问题,base64要比二进制编码大1/3。在处理图片的过程中会多次涉及datauri,但是最终没有用它做传输格式,因为我们的后台存的都是单独的图片文件。

2.实现流程

  uploadHelper=function(event,imgSize,returnType,callback)

          这个是暴露的程序入口,需要放到文件input的onchange监听事件回调中。第一个event就是这个change事件,之后的参数是图片尺寸,输出类型,完成回调。

下面是一个例子,其中dataUri是一个img标签

var oFile=document.querySelector(‘#file-input‘);    var oDataUri=document.querySelector(‘dataUri‘);    oFile.onchange=function (event) {        uploadHelper(event,{width:100,height:100},‘dataUri‘,function (dataURI) {            document.querySelector(‘#dataUri‘).src=http://www.mamicode.com/dataURI;        });    };

    下面按照数据流来说明处理过程,这一系列过程中存在大量异步回调,所以数据流和程序编写顺序有些区别。 

    用event.target.file[0]拿到文件之后调用

function compressImage(file,size,callback)

   这个方法是resize图片的主程序,然而这个方法没什么实际内容。其中会调用方法

fileToDataUrl(file,function (dataUrl)

     这个方法的作用是将file转换成dataUri,当然这一步并不是必需的。

   转换成datauri之后就到了压缩的核心方法

function compressDataUrl(dataURL,size,callback)

   这个方法的思路是创建一个图片实例,将之前得到的datauri赋给它的img.src,然后使用canvas的图片重绘方法

ctx.drawImage(img,cutL,cutT,cutW,cutH,0,0,canvas.width,canvas.height);

   参考文献:http://www.w3school.com.cn/tags/canvas_drawimage.asp

   关于drawImage,首先这个方法是不是在canvas上,而是在canvas的上下文(context)上的一个方法。

   其次,这个方法的参数比较多,因为这个方法需要让你指定用哪个图片作为源文件(img),之后四个cut开头的参数是让用户指定原图上绘制的起始坐标(cutL,cutT),然后

   指定取原图多长多宽进行绘制(cutW,cutH)。之后是在canvas画布的哪个坐标开始绘制(0,0)最后是指定画布上新图像的宽高。其中除了0,0 以及我们指定的新图片大小以外都      需要进行计算。计算的思路是:既然指定了新图片的长宽,那么要想让新图片不发生长或者宽的拉伸/压缩,需要保证原图宽高比和新图一致,如果不一致就裁剪掉。裁剪的时候默    认是左右对称裁剪,取得中间部分。

   绘制结束之后将canvas转成datauri格式。值得一提的是,对于某一格式,图片大小基本是和尺寸相关的,100*100的图片只有5k左右大小

   如果你需要将文件作为表单的一项上传,也许你还需要转成blob文件。实际上,对于有input=file表单(请求格式:multipart/form-data),

   其中的文件(非字符串)上传都是用的blob格式。转化可以使用方法

   function dataUriToBlob(dataUri)

   这个方法做的事情就是把dataUri的字符串分隔解析,因为datauri除了数据还有文件格式。

   最后创建blob文件。

3.后台接收

   在这之后有一个问题困扰了我许久:blob文件后台怎么转成原来的格式(比如jpg)?

   在我面对收到的blob文件一脸懵逼的许久之后,请教了老张,老张很自然的打开了blob文件所在的文件夹,然后我看到了图片预览。。。(至少ubuntu下是可以看的)

   这时候我才知道,实际上是不用转格式的,我差的只是一个后缀。(比如.jpg)

    然后稍微改了下multer的设置就可以了。

http://www.w3school.com.cn/tags/canvas_drawimage.asp

头像上传二三事