JS前端图片压缩上传

JS前端图片压缩上传重点知识

最近在做一个手机端的图片上传,写了一个比较符合自己要求的方法,可供参考

在做这个功能模块时,我遇到了以下问题,都花费了大量时间:

1. 不知道怎么压缩图片,(代码和方法)
2. 得到图片压缩后的base64值,也可以预览,但却传不到后端去
3. 怎么确保我想要压缩的所有图片,大小都相近,图片还尽可能的清晰
(如我参考了网上的代码,基本都是按照比例压缩如1/2或1/4,那一个10m的图片压缩完后还有5m或者2.5m,意义不大,那你说比例调大些,按照1/10比例压缩,这样万一我上传的文件只有200k,这样一压缩图片就严重失真了)
4. 将文件发送到后端时携带参数问题

代码没有捷径可走啊!!····

=-目前博主引用的是jQuery和layui框架,如不用layui框架注释掉相应的样式即可,影响的只有界面,可能要稍稍修改HTML

实例代码如下:

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2021/2/22
  author: xumz
  To change this template use File | Settings | File Templates.
  搬运请备注
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!-- meta使用viewport以确保页面可自由缩放 -->
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
    <title>身份验证</title>
     <%--引用jQuery和layui框架,如不用layui框架注释掉相应的样式即可,影响的只有界面--%>
    <script src=" ../js/jquery-1.9.1.min.js"></script>
    <script src="../js/layui/layui.js"></script>
    <link rel="stylesheet" href="../js/layui/css/layui.css" media="all">
    <style type="text/css">

        [id^="layui-layer"] {
     
            border-radius: 9px !important;
        }

        .up_img_showborder {
     
            border: 1px rgba(143, 143, 143, 0.43) dashed;
            width: 85%;
            height: 165px;
            margin: 25px;
        }

        #img_one {
     
            border: 1px #F2F2F2 solid;
            max-width: 96%;
            max-height: 160px;
            /*padding: 4px;*/
        }

        .icon_style {
     
            font-size: 50px;
            color: #efefef;
            line-height: 100px;
        }
    </style>

</head>

<body>

<div style="width: 90%;height: 100%;margin: auto;" align="center">

    <div id="upload_img01" class="up_img_showborder">
        <div id="hiden_one">
            <i class="layui-icon layui-icon-addition icon_style"></i>
            <p style="color: gray">点击上传图片</p>
        </div>

        <div class="layui-hide" id="uploadDemoView">
            <img class="layui-upload-img" id="img_one">
        </div>
    </div>

    <div>
        <input type="button" class="layui-btn layui-btn-normal layui-btn-lg" onclick="next_btn(this)" value="确认">
    </div>

    <div>
        <input type="file" style="visibility: hidden" accept="image/*" id="btn1">
    </div>

</div>

<script type="text/javascript">

    //引用layui不可少
    layui.use(['form', 'layer', 'upload'], function () {
     
        var form = layui.form
            , layer = layui.layer
            , upload = layui.upload;
    });

    /*点击上传正面图片*/
    $(document).on('click', '#upload_img01', function () {
     
        document.getElementById("btn1").click();
    });

    var BlobDealImg = null;

    /*input数据改变时,获取文件数据,上传正面*/
    $("#btn1").change(function () {
     
        console.log(this.files[0].size);
        let up_ImgBase64 = this.files[0];	//获取文件对象
        if (null != up_ImgBase64 && up_ImgBase64 != "") {
     
            layer.msg("图像采集成功!");
            var reader = new FileReader();
            reader.readAsDataURL(up_ImgBase64);	//将读取的文件转换成base64格式
            reader.onload = function (e) {
     
                var dataBase64 = e.target.result; //result是你读取到的文件内容,此属性读取完成才能使用
                // console.log('dataBase64==='+dataBase64);
                dealImage(dataBase64);
                setTimeout(function () {
     
                    console.log(BlobDealImg);
                }, 50);
            }
        } else {
     
            layer.open({
     
                title: ['提示', 'border-radius: 6px;']
                , shadeClose: true
                , resize: false
                , content: '图像采集失败,请重新采集!'
            });
        }
    });

    function dealImage(base) {
     
        let image = new Image();    //新建一个img标签(不嵌入DOM节点,仅做canvas操作)
        image.src = base;   //让该标签加载base64格式的原图
        image.onload = function () {
         //图片加载完毕后再通过canvas压缩图片,否则图片还没加载完就压缩,结果图片是全黑的
            let canvas = document.createElement('canvas'), //创建一个canvas元素
                context = canvas.getContext('2d'),    //context相当于画笔,里面有各种可以进行绘图的API
                originWidth = image.width,/* 图片的宽度 */
                originHeight = image.height, /* 图片的高度 */
                data = '';    //存储压缩后的图片

            // 设置最大尺寸限制,将所有图片都压缩到小于1m
            const maxWidth = 1024, maxHeight = 1024;
            // 需要压缩的目标尺寸
            let targetWidth = originWidth, targetHeight = originHeight;
            // 等比例计算超过最大限制时缩放后的图片尺寸
            if (originWidth > maxWidth || originHeight > maxHeight) {
     
                if (originWidth / originHeight > 1) {
     
                    // 宽图片
                    targetWidth = maxWidth;
                    targetHeight = Math.round(maxWidth * (originHeight / originWidth));
                } else {
     
                    // 高图片
                    targetHeight = maxHeight;
                    targetWidth = Math.round(maxHeight * (originWidth / originHeight));
                }
            }
            canvas.width = targetWidth;   //设置绘图的宽度
            canvas.height = targetHeight;   //设置绘图的高度
            //使用drawImage重新设置img标签中的图片大小,实现压缩。drawImage方法的参数可以自行查阅W3C
            context.drawImage(image, 0, 0, targetWidth, targetHeight);

            //使用toDataURL将canvas上的图片转换为base64格式
            data = canvas.toDataURL('image/jpg');

            $('#hiden_one').addClass('layui-hide');//隐藏区域中的icon和文字
            $('#uploadDemoView').removeClass('layui-hide'); //打开隐藏的image标签
            document.getElementById('img_one').src = data;//将压缩后的图片显示到页面上的img标签
            //将base64转为blob文件对象
            BlobDealImg = convertBase64UrlToBlob(data);
            // console.log(BlobDealImg);
            //上传文件携带参数问题解决
            var formData = new FormData();//这里需要实例化一个FormData来进行文件上传
            formData.append("file", BlobDealImg, "file_" + Date.parse(new Date()) + ".jpg");//文件
            formData.append("data2", "12345");//参数1
            formData.append("data1", "023");
            
            //做到这一步前端的所有代码就已经写完了,接下来只需要后端接收即可
            
            /* $.ajax({
                 url: '', //改成您自己的上传接口
                 data: formData,
                 type: "post",
                 processData: false,//不需要将传输的数据序列化,必须这么写
                 contentType: false,
                 // dataType: "json",
                 success: function (res) {

                 },

             });*/
        }
    };

    /*将base64转为blob文件对象,再上传*/
    function convertBase64UrlToBlob(urlData) {
     
        var arr = urlData.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
     
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {
     type: mime});
    }

</script>
</body>
</html>

运行界面如下:
JS前端图片压缩上传_第1张图片

JS前端图片压缩上传_第2张图片

你可能感兴趣的