利用FileReader和FormData实现图片预览和上传(base64转二进制文件)
来源:互联网 发布:魅族手机怎么关4g网络 编辑:程序博客网 时间:2024/05/22 12:09
业务有个需求,要做图片预览上传,过去都是客户端上传给后端,后端返回 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 type="file">
input.on.('change', preview);
预览
预览使用 FileReader
对象来读:
function preview(e) { var file = e.target.files[0]; var reader = new FileReader(); reader.onloadend = function () { // 图片的 base64 格式, 可以直接当成 img 的 src 属性值 var dataURL = reader.result; var img = new Image(); img.src = dataURL; // 插入到 DOM 中预览 // ... }; reader.readAsDataURL(file); // 读出 base64}
提交图片文件(二进制文件 非 base64)
base64 转 二进制文件
/** * dataURL to blob, ref to https://gist.github.com/fupslot/5015897 * @param dataURI * @returns {Blob} */function dataURItoBlob(dataURI) { var byteString = atob(dataURI.split(',')[1]); var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], {type: mimeString});}
构造 FormData
填充二进制文件数据,通过 ajax
的方式进行提交:
var fd = new FormData();var blob = dataURItoBlob(dataURL);fd.append('file', blob);$.ajax({ type: 'POST', url: '/upload', data: fd, processData: false, // 不会将 data 参数序列化字符串 contentType: false, // 根据表单 input 提交的数据使用其默认的 contentType xhr: function() { var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; console.log('进度', percentComplete); } }, false); return xhr; }}).success(function (res) { // 拿到提交的结果}).error(function (err) { console.error(err);});
注意:不要漏了指定 processData
和 contentType
为 false
。
压缩
业务中不需要前端不需要压缩,因为后端有更靠谱的压缩方案,但是前端其实也可以压缩,那就是用 canvas
把图画出适合的大小,然后上传。
主要流程:
- 在
new
出来的Image
对象,我们监听它的onload
事件 - 按照压缩比例,算出压缩后的图片尺寸
- 创建
canvas
,尺寸设置成上一步骤算出来的压缩后的图片尺寸 - 调用
drawImage
方法,把图片绘制到canvas
中 - 调用
canvas
的toDataURL
,取出base64
格式的数据 - 后续的传图步骤和上面的原图上传一样
var img = new Image();img.onload = function () { // 当图片宽度超过 400px 时, 就压缩成 400px, 高度按比例计算 // 压缩质量可以根据实际情况调整 var w = Math.min(400, img.width); var h = img.height * (w / img.width); var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); // 设置 canvas 的宽度和高度 canvas.width = w; canvas.height = h; // 把图片绘制到 canvas 中 ctx.drawImage(img, 0, 0, w, h); // 取出 base64 格式数据 var dataURL = canvas.toDataURL('image/png'); // ...};img.src = reader.result;
自己的 OneWord
客户端的上传组件就是这么做的: ow-image-uploader.vue
这样一看,好像除去业务逻辑的话,好像也没多少代码
PS:需要注意的是,通过 canvas
绘制的图片,低版本 IOS
会出现比例不正确的情况,请参考 https://github.com/stomita/ios-imagefile-megapixel
0 0
- 利用FileReader和FormData实现图片预览和上传(base64转二进制文件)
- FileReader和FormData实现图片上传和预览
- js实现图片预览和FormData上传
- 利用html5的FileReader对象实现图片预览,利用FormData对象结合struts2实现无刷新文件上传(多参数)
- FileReader+Ajax+PHP实现异步上传图片和预览
- html5的FileReader实现图片上传预览并生成base64
- 利用FileReader实现图片预览
- jquery和thinkphp利用formData属性ajax上传并,添加水印,裁剪,实现预览
- FormData图片预览上传
- 使用 FileReader 实现图片预览和拖放图片
- FileReader图片预览上传
- FileReader上传图片预览
- HTML5 FileReader base64图片预览
- 利用struts实现jsp中的图片上传和预览
- FileReader 实现预览图片
- js本地预览图片和转base64
- FileReader实现上传图片时的图片预览
- FileReader 获取图片BASE64 代码 并预览
- Qt之窗体任意拖拽两种方法
- iOS8中storyboard中autolayout和size class的使用
- 第四周 项目3 【单链表应用1】
- mysql 利用explain优化sql
- 火狐浏览器崩溃的问题
- 利用FileReader和FormData实现图片预览和上传(base64转二进制文件)
- 关于git的使用记录
- 关于SPI_160918
- ROS_Kinetic_x 基於ROS和Gazebo的RoboCup中型組仿真系統(多機器人協作)
- 数据结构顺序表应用
- Okhttp 3.X 当中 FormEncodingBuilder没有
- Maven的pom.xml介绍
- 图文混排Button
- 手机端wap站网页播放腾讯视频代码