H5利用FileReader和FormData实现图片预览和上传(base64转二进制文件)

业务有个需求,要做图片预览上传,过去都是客户端上传给后端,后端返回url前端进行预览,现在其实可以不依赖后端做预览,最后在上传,这主要依赖FileReader和FormData这两个对象和JavaScript处理二进制的能力。

OK,Show code~,以下代码已注释掉具体业务逻辑和实现,如果需要了解 API 细节,可以请参考:

https://developer.mozilla.org/en-US/docs/Web/API/FileReader

https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData

https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

监听表单文件变化

文件表单的样式主要通过让它后面,通过别的DOM来美化它。

input.on.('change', preview);

预览

预览使用FileReader对象来读:

functionpreview(e){varfile = e.target.files[0];varreader =newFileReader();    reader.onloadend =function(){// 图片的 base64 格式, 可以直接当成 img 的 src 属性值vardataURL = reader.result;varimg =newImage();        img.src = dataURL;// 插入到 DOM 中预览// ...};    reader.readAsDataURL(file);// 读出 base64}

提交图片文件(二进制文件 非 base64)

base64 转 二进制文件

/*** dataURL to blob, ref to https://gist.github.com/fupslot/5015897 *@paramdataURI *@returns{Blob} */function dataURItoBlob(dataURI) {    var byteString = atob(dataURI.split(',')[1]);    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];    var ab =newArrayBuffer(byteString.length);    var ia =newUint8Array(ab);for(var i =0; i < byteString.length; i++) {        ia[i] = byteString.charCodeAt(i);    }returnnewBlob([ab], {type: mimeString});}

构造FormData填充二进制文件数据,通过ajax的方式进行提交:

varfd =newFormData();varblob = dataURItoBlob(dataURL);fd.append('file', blob);$.ajax({    type:'POST',    url:'/upload',    data: fd,    processData:false,// 不会将 data 参数序列化字符串contentType:false,// 根据表单 input 提交的数据使用其默认的 contentTypexhr:function() {varxhr =newwindow.XMLHttpRequest();        xhr.upload.addEventListener("progress",function(evt) {if(evt.lengthComputable) {varpercentComplete = evt.loaded / evt.total;                console.log('进度', percentComplete);            }        },false);returnxhr;    }}).success(function(res){// 拿到提交的结果}).error(function(err){console.error(err);});

注意:不要漏了指定processData和contentType为false。

压缩

业务中不需要前端不需要压缩,因为后端有更靠谱的压缩方案,但是前端其实也可以压缩,那就是用canvas把图画出适合的大小,然后上传。

主要流程:

在new出来的Image对象,我们监听它的onload事件

按照压缩比例,算出压缩后的图片尺寸

创建canvas,尺寸设置成上一步骤算出来的压缩后的图片尺寸

调用drawImage方法,把图片绘制到canvas中

调用canvas的toDataURL,取出base64格式的数据

后续的传图步骤和上面的原图上传一样

varimg =newImage();img.onload =function(){// 当图片宽度超过 400px 时, 就压缩成 400px, 高度按比例计算// 压缩质量可以根据实际情况调整varw = Math.min(400, img.width);varh = img.height * (w / img.width);varcanvas = document.createElement('canvas');varctx = canvas.getContext('2d');// 设置 canvas 的宽度和高度canvas.width = w;    canvas.height = h;// 把图片绘制到 canvas 中ctx.drawImage(img,0,0, w, h);// 取出 base64 格式数据vardataURL = canvas.toDataURL('image/png');// ...};img.src = reader.result;

自己的OneWord客户端的上传组件就是这么做的:ow-image-uploader.vue

这样一看,好像除去业务逻辑的话,好像也没多少代码

PS:需要注意的是,通过canvas绘制的图片,低版本iOS会出现比例不正确的情况,请参考https://github.com/stomita/ios-imagefile-megapixel

原地址:http://blog.csdn.net/huanghongfei1/article/details/61216852

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容