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

贾菌
• 阅读 9873

最近在使用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 type="file">
input.on.('change', preview);
function preview(e) {
      // 获取到input-file的文件对象
    var file = e.target.files[0];
    ...
}
  • 浏览器缓存图片的base64 [ window.URL.createObjectURL(file) ]

<input type="file" name="imgOne" id="imgOne" onchange="preImg(this.id,'imgPre');" />
// 结果: "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) ]

<input type="file" onchange="previewFile()"><br>
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请求参数拼接方式),其具体值是编码好的:

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

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

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

如果有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){}
                    });

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

网上找了一些相关的方法与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...

欢迎指点,指错!谢谢!

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
tp3.2读取excel文件
使用PHPExcel时,首先要下载PHPExcel并放在ThinkPHP/Library/Vendor下1.创建html文件(文件上传按钮)<formaction"{:U('控制器名/方法名')}"method"post"enctype"multipart/formdata" 
Easter79 Easter79
3年前
springboot项目文件上传(绝对路径)并使用tomcat虚拟路径进行图片预览
前言项目中,需要上传文件,但是可能会比较多,所以不能放入项目目录中,需要指定目录并按顺序放置。并且:还需要这些数据可以预览(图片等)。那么问题就是:上传完成之后我存入服务器,并拿到绝对路径,存入数据库,那么,前台访问的时候请求地址肯定是:ip端口项目名,那么该如何获取资源呢?正文:1\.文件上传到指定目录(服务
Easter79 Easter79
3年前
springboot项目上传文件出现临时文件目录为空
<divid"cnblogs\_post\_body"class"blogpostbody"<p最近写文件上传到服务器读取的代码,前端使用FormData上传,服务端用MultipartFile接收,自己测试了下MultipartFile对象有什么东西,结果一般属性都能出来,测试getInputStrea()方法的时候出现了以下错误,简单一
CuterCorley CuterCorley
4年前
uni-app入门教程(5)接口的基本使用
前言本文主要介绍uniapp提供的一些基础接口,包括:网络请求接口,用于通过指定的请求方法,携带特定的数据,向特定的地址请求并返回请求结果;图片处理接口,包括选择、预览、获取信息、保存到本地等接口;文件处理接口,包括文件上传和下载接口;数据缓存接口,包括以同步或异步的方式保存、获取或删除数据的接口。一、网络请求小程序要想正常运转,都需要与服务器端进
Stella981 Stella981
3年前
C# 请求数据 使用post的方式提交raw格式的数据,数据为json格式,多层嵌套
原文地址:https://cnodejs.org/topic/539ff8a5c3ee0b5820938d60raw方式使用的是纯字符串的数据上传方式,所以在POST之前,可能需要手工的把一些JSON格式的数据转换成字符串的(加两单引号)Formdata的方式就是keyvalue的提交,数据其实是分割的Formdata是键值对,你只能通
Stella981 Stella981
3年前
Play 2.0 用户指南 - 文件上传 -- 针对Scala开发者
   处理文件上传   在form中指定multipart/formdata属性上传文件   上传文件的标准方式是指定form的一个特殊属性multipart/formdata,可以让你混合表单数据和表单文件附件。   开始编写HTML表单:@form(actionrou
Wesley13 Wesley13
3年前
PHP实现图片(文件)上传
这几天整理做过的php项目,感觉这个经常会用到,传上来共享一下咯首先,前端界面1、表单的首行需要加上enctype"multipart/formdata",需要上传的图片必须设置type"file"表示选择文件<formid"img_form"method"post"class"formhorizontal"r
Stella981 Stella981
3年前
Django
一:form表单标签的文件上传1:浏览器:html文件<h4form文件上传</h4<formaction"/file_put/"method"post"enctype"multipart/formdata"{%csrf_token
Stella981 Stella981
3年前
Fastdfs安装_nginx进行图片动态压缩
说明1.因为上传的图片较大,部分页面直接引用图片地址,则造成页面加载缓慢问题。2.考虑到服务器空间问题,我们没有进行上传缩略图。仅仅是上传了原图3.为了优化页面加载图片的时间问题,所以对图片进行动态缩放。PS:如果访问量较高,建议进行存储缩略图图片缩放采用nginx的http\_image\_filter\_module
Stella981 Stella981
3年前
Javascript验证上传图片大小[前台处理]
需求分析:在做上传图片的时候,如果不限制上传图片大小,后果非常的严重。那么我们怎样才可以解决一个棘手的问题呢?有两种方式:1)后台处理:也就是AJAXPOST提交到后台,把图片上传到服务器上,然后获得该图片大小做处理。2)前台处理:也就是利用Javascript获取该图片大小。显然第一种方式,很不好。因为需要把文件先上传到
Immerse Immerse
6个月前
我悟了!原来本地图片预览还能这样搞
在网页开发中,经常会遇到需要让用户上传图片并在上传前进行预览的需求。这样做的好处显而易见:用户可以立即看到自己选择的图片是否正确,避免了不必要的上传和服务器资源浪费,提升了用户体验。