js压缩图片(ajax上传)

js压缩图片(ajax、form提交)(pc、mobile测试ok)(Java)

1. 目的:

上传先进行图片压缩,然后再把压缩后的图片上传到服务器。

2. 思路:

上传前用js对图片压缩,把利用canvas生成的base64字符串,传入后台,(无所谓ajax或者form,同时也可以解决图片无刷新上传),在Java后台将获取到的base64字符串输出为图片,即可。

3. 代码:

引用mobileBUGFix.mini.js(移动端的补丁)

<!DOCTYPE>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>上传前js压缩图片(ajax、form提交)(pc、mobile测试ok)(Java)</title>
</head>

<script type="text/javascript" src="jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="mobileBUGFix.mini.js"></script>
<script type="text/javascript">

    var pre;//源图片名称

    /**
     * 获得base64
     * @param {Object} obj
     * @param {Number} [obj.width] 图片需要压缩的宽度,高度会跟随调整
     * @param {Number} [obj.quality=0.8] 压缩质量,不压缩为1
     * @param {Function} [obj.before(this, blob, file)] 处理前函数,this指向的是input:file
     * @param {Function} obj.success(obj) 处理后函数
     *
     */
    $.fn.localResizeIMG = function(obj) {
        this.on('change', function() {
            var file = this.files[0];
            pre = file.name;
            var URL = window.URL || window.webkitURL;
            var blob = URL.createObjectURL(file);

            // 执行前函数
            if ($.isFunction(obj.before)) {
                obj.before(this, blob, file);
            }

            _create(blob, file);
            this.value = ''; // 清空临时数据
        });

        /**
         * 生成base64
         * @param blob 通过file获得的二进制
         */
        function _create(blob) {
            var img = new Image();
            img.src = blob;

            img.onload = function() {
                var that = this;

                //生成比例
                var w = that.width, h = that.height, scale = w / h;
                w = obj.width || w;
                h = w / scale;

                //生成canvas
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                $(canvas).attr({
                    width : w,
                    height : h
                });
                ctx.drawImage(that, 0, 0, w, h);

                /**
                 * 生成base64
                 * 兼容修复移动设备需要引入mobileBUGFix.js
                 */
                var base64 = canvas.toDataURL('image/jpeg', obj.quality || 0.8);

                // 修复IOS
                if (navigator.userAgent.match(/iphone/i)) {
                    var mpImg = new MegaPixImage(img);
                    mpImg.render(canvas, {
                        maxWidth : w,
                        maxHeight : h,
                        quality : obj.quality || 0.8
                    });
                    base64 = canvas.toDataURL('image/jpeg', obj.quality || 0.8);
                }

                // 修复android
                if (navigator.userAgent.match(/Android/i)) {
                    var encoder = new JPEGEncoder();
                    base64 = encoder.encode(ctx.getImageData(0, 0, w, h),
                            obj.quality * 100 || 80);
                }

                // 生成结果
                var result = {
                    base64 : base64,
                    clearBase64 : base64.substr(base64.indexOf(',') + 1)
                };

                // 执行后函数
                obj.success(result);
            };
                }
            };

    $(function() {

        $("input[type=file]").each(function() {
            var _this = $(this);
                _this.localResizeIMG({
                    width : 400,
                    quality : 0.001,
                    success : function(result) {

                        //获取后缀名
                        var att = pre.substr(pre.lastIndexOf("."));
                        //压缩后图片的base64字符串
                        var base64_string = result.clearBase64;
                        //图片预览
                        var imgObj = $("#img");
                        imgObj.attr("src",                      "data:image/jpeg;base64," + base64_string)                                      .show();
                        //拼接data字符串,传递会后台
                        var fileData = $("#fileData");
                        fileData.val(att + "," + imgObj.attr("src"));

                        //此处可直接使用ajax上传,也可存于form,表单提交上传
                        //此处例子使用ajax提交
                        $.ajax({
                            type : "POST",
                            url : "<%=request.getContextPath()%>/doUploadImg",
                            data :{
                                imgData : fileData.val()
                            },
                            dataType : "json",
                            success : function(msg){
                                alert(msg);
                            }
                    });
                }
            });
        });

    });
</script>

<body>
    <p>上传前js压缩图片(ajax、form提交)(pc、mobile测试ok)(Java)</p>
    选择文件:
    <input id="file" class="form-control" type="file" accept="image/*" name="file1">
    <img id="img" name="img" width="200" height="100"   style="display: none;" />
    <input type="text" id="fileData" name="fileData" />
</body>
</html>

4. localResizeIMG参数:

width:缩略图宽度
quality:图片质量,0—1,越大越好
localResizeIMG返回值

5. localResizeIMG使用:

result.base64:
    带图片类型的base64编码,可直接用于img标签的src,如"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/…2wBDAAYEBQYFBAY”;
result.clearBase64:
    不带图片类型的编码,如“/9j/4AAQSkZJRgABAQAAAQABAAD/…2wBDAAYEBQYFBAY”
$(document).ready(function(e) {
   $('input:file').localResizeIMG({
      width: 400,
      quality: 1,
      success: function (result) {  
        var base64_string = result.clearBase64, 
      }
  });
});

6. 保存文件

在上面一步中,我们把base64_string 通过ajax传入到doUploadImg中,接下来我们就要在doUploadImg中接收base64参数,把它转换成img文件保存来服务器中,并给出提示。

package cn.gluepudding.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


@WebServlet("/doUploadImg")
public class DoUploadImg extends HttpServlet {

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();

        // 获取参数
        String imgData = request.getParameter("imgData");

        // 绝对路径
        String path = request.getSession().getServletContext().getRealPath("upload");
        File targetFile = new File(path);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }

        // 生成新的图片名称(入库)
        String imgSuffix = imgData.split(",")[0];
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + imgSuffix;

        boolean flag = GenerateImage(imgData.split(",")[2], fileName, path);

        out.print(flag);
        out.flush();
        out.close();

    }

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }


    // 将base64字符文件输出图像
    public static boolean GenerateImage(String imgStr, String fileName, String path) {
        // 对字节数组字符串进行Base64解码并生成图片
        if (imgStr == null) // 图像数据为空
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            // 生成jpeg图片
            String imgFilePath = path + "\\" + fileName;// 新生成的图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 图片转化成base64字符串
    public static String GetImageStr() {
        // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        String imgFile = "d://test.jpg";// 待处理的图片
        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);// 返回Base64编码过的字节数组字符串
    }

}

7. 不足之处:

当图片宽度小于localResizeIMG设置的width参数时,图片会被拉申,从而引起图片失真(比如width高为600,图片只在400px时,压缩后的图片就变成了600px,图片尺寸变大了,会失真)。

8. Demo下载

http://pan.baidu.com/s/1o68area

参考资料
http://www.cnblogs.com/manongxiaobing/p/4720568.html
http://blog.csdn.net/hfhwfw/article/details/5544408

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值