本地图片预览,裁切,压缩,Base64 / FormData / jQuery.form,异步上传

最近在使用mui做一几个页面,需要拍照后上传到服务器一些图片。其中在上传之前,可多选择多张,可以预览,可以缩放,可以删除,因此在这个过程中也找了不少的知识点,也走了不少的弯路,写在这里,为了分享与查询。

这次分享的知识点:

  1. FormData 为二进制异步上传方法,上传的数据与文件是 1:1 的

  2. Base64 为二进制数据表示方法,文件越大,体积越大,可用在 canvas 裁切预览,预览本地图片在浏览器上,不建议在上传时使用。转成base64之后,最大的好处就是可以绘制到Canvas上,然后对图片进行编辑!

  3. jQuery.form 为二进制异步上传方法

如果在上传前,图片文件已经转成 Base64 ,但是想要通过 FormData 上传文件时,需要将 Base64 转成 Blob 对象,最后将 Blob 对象 append 到 FormData 中,将FormData做为参数上传到服务器。所以有句话叫做:
既然都用FormData了,还转个毛线base64啊!

下面分别介绍:

预览功能:
http://www.jb51.net/article/4...
http://www.jb51.net/article/7...
https://www.oschina.net/code/...

  • 获取上传前,存在浏览器中的图片地址(或对象)


input.on.('change', preview);
function preview(e) {
      // 获取到input-file的文件对象
    var file = e.target.files[0];
    ...
}
  • 浏览器缓存图片的base64 [ window.URL.createObjectURL(file) ]


// 结果: "blob:null/1342ae24-b5da-4ec3-b05d-f385387bd881"
window.URL.createObjectURL(document.getElementById('imgOne').files[0]);
//JS预览图像将本地图片显示到浏览器上
document.getElementById(' imgPre ').src=' blob:null/1342ae24-b5da-4ec3-b05d-f385387bd881 ';
  • 实际上传图片的base64 [ new FileReader().readAsDataURL (file) ]


var reader = new FileReader(); reader.onloadend = function () { // Base64内容 preview.src = reader.result; } reader.readAsDataURL( document.querySelector('input[type=file]').files[0] );
  • 利用 canvas 在浏览器中实现预览

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;

压缩功能:
压缩没怎么研究,从网上找的相对可用的资源,贴在这里,方便查询

  • javascript - 在移动端怎样上传图片?,而且在上传前把图片压缩一定的大小?

https://segmentfault.com/q/10...

  • 借助插件 lrz.mobile.min.js

[lrz.bundle.js 前端图片压缩] think2011/localResizeIMG: 前端本地客户端压缩图片,兼容IOS,Android,PC、自动按需加载文件

https://github.com/think2011/...

  • 上传前的图片压缩逻辑之一,就是在前端把base64转成二级制数据,这个数据体积相比base64小很多,还可以塞到formdata中提交

我在我的项目中有用到过,是因为图片需要预览,也需要上传,总体感觉不太好。

Base64异步提交

  1. 利于canvas,实现图处在线预览

  2. 利用new FileReader,实现图片转Base64

  • 读出 base64

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 中预览
        // ...
    };
   
    // 读出 base64
    reader.readAsDataURL(file);
}
  • base64 转 二进制文件,也就是base64 转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});
}

  • blob对象是可以通过 FormData 异步提交的

var imgaeBlob = dataURItoBlob(dataURI);
var formData = new FormData();
formData.apppend('images',imgaeBlob);

mui.ajax({
        type: "post",
        url: url,
        data: formData,
        cache: false,
        processData: false,
        contentType: 'enctype="multipart/form-data'
});

jQuery.form异步提交

  • 使用jQuery.form插件,实现完美的表单异步提交

http://www.cnblogs.com/heyuqu...

  • 两种实现表单提交的方法

var options = {
    url: 'async_submit_test1.aspx?action=SaveUserInfo',
    type: 'post',
    dataType: 'text',
    data: $("#form1").serialize(),
    success: function (data) {
    if (data.length > 0)
        $("#responseText").text(data);
    }
};
$.ajax(options);

var options = {success: function (data) {$("#responseText").text(data);} };
// ajaxForm
$("#form1").ajaxForm(options);
// ajaxSubmit
$("#btnAjaxSubmit").click(function () {
    $("#form1").ajaxSubmit(options);
});

FormData异步提交:

  1. post,提交时的 contentType,影响返回的数据的查看(我是这么理解的):

  2. application/x-www-form-urlencoded (常见的)

  3. multipart/form-data (图片文件上传时常设置)

  4. 如果在提交的表单中除了图片外还有其它类型的,必须分别 appentd 到 formData 中

application/x-www-form-urlencoded 这种格式最为常见,平时使用的ajax提交就是这种方式。对应postman上的x-www-form-urlencoded选项,请求头中Content-Type为application/x-www-form-urlencoded;charset=utf-8,其中请求的数据被编码为key=value&key=value的形式(没错,类似浏览器地址栏中的get请求参数拼接方式),其具体值是编码好的:

multipart/form-data 当表单提交内容中包含文件时(比如图片文件),则需要这种数据格式。通常要设置表单enctype="multipart/form-data":

如果有text的input,可以这样写。如果有多个值,可以多次 append():


      var formData = new FormData();
      formData.append("images[]", fileBlob);
      formData.append('text',ticketDes);
      
                    $.ajax({
                        type: "post",
                        url: dd.baseUrl + '/save.html',
                        data: formData,
                        cache: false,
                        processData: false,
                        contentType: 'enctype="multipart/form-data',
                        sucess:function(data){}
                    });

网上找了一些相关的方法与demo:

  • 使用FormData对象提交表单及上传图片

http://blog.csdn.net/fdipzone...

  • FormData将图片转为 base64 上传

var fromData = new FormData();
fromData.append("base64", e.target.result);
  • 通过FileReader获取图片的base64

http://www.cnblogs.com/simonb...

  • FormData 自定义(二进制)上传

var fd = new FormData();
var blob = dataURItoBlob(dataURL);
fd.append('file', blob);


dataURI 为 base64 
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});
}
  • 利用FileReader和FormData实现图片预览和上传

http://www.tuicool.com/articl...

欢迎指点,指错!谢谢!

你可能感兴趣的:(base64,formdata)