曾写过在前端把图片按比例压缩不失真上传服务器的前端和后台,可惜没有及时做总结保留代码,只记得js利用了base64位压缩和Exif.js进行图片处理,还有其中让我头疼的ios拍照上传后会倒置等诸多问题,当时也是在看了网上的各种代码后才有思路进行编写,希望留下一些大佬的代码在以后小弟我方便学习

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
 
<body>
    <div>
        <img src="imgzip.jpg" alt="" width="350">
        <img alt="" id="transform">
    </div>
    <script>
        /**
 * 图片压缩,默认同比例压缩
 * @param {Object} path
 *   pc端传入的路径可以为相对路径,但是在移动端上必须传入的路径是照相图片储存的绝对路径
 * @param {Object} obj
 *   obj 对象 有 width, height, quality(0-1)
 * @param {Object} callback
 *   回调函数有一个参数,base64的字符串数据
    quality 图片缩放比例0-1 越大越清晰
 */
        // 调用函数处理图片                 
        dealImage("imgzip.jpeg", {
            // 注意:在pc端可以用绝对路径或相对路径,移动端最好用绝对路径
            // width: 1000,
            quality: 0.5
        }, function (base) {
            document.getElementById("transform").src = base;
            var mb = showSize(base);
        })
        function showSize(base64url) {
            //获取base64图片大小,返回字节
            var str = base64url.replace('data:image/png;base64,', '');
            var equalIndex = str.indexOf('=');
            if (str.indexOf('=') > 0) {
                str = str.substring(0, equalIndex);
            }
            var strLength = str.length;
            var fileLength = parseInt(strLength - (strLength / 8) * 2);
            console.log("压缩后的图片size", fileLength + "B")
            return fileLength;
        }
 
        function dealImage(path, obj, callback) {
            var img = new Image();
            img.src = path;
            img.onload = function () {
                var that = this;
                var ext = path.substring(path.lastIndexOf(".") + 1).toLowerCase();
                // 默认按比例压缩
                var w = that.width,
                    h = that.height,
                    scale = w / h;
                w = obj.width || w;
                h = obj.height || (w / scale);
                var quality = obj.quality;  // 默认图片质量为0.7,可以为image/jpeg或image/webp类型的图片设置图片质量,取值0-1,超出则以默认值0.92替代
                //生成canvas
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                // 创建属性节点
                var anw = document.createAttribute("width");
                anw.nodeValue = w;
                var anh = document.createAttribute("height");
                anh.nodeValue = h;
                canvas.setAttributeNode(anw);
                canvas.setAttributeNode(anh);
                ctx.drawImage(that, 0, 0, w, h);
                // 图像质量
                if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
                    quality = obj.quality;
                }
                // quality值越小,所绘制出的图像越模糊
                console.log("tup", ext)
                var base64 = canvas.toDataURL('image/jpeg', quality);
                // 回调函数返回base64的值
                callback(base64);
            }
        }
    </script>
</body>
 
</html>

上传前不失真,有需要的去做按比例压缩(算法自己想)

html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题;Android手机没这个问题。

因此解决这个问题的思路是:获取到照片拍摄的方向角,对非横拍的ios照片进行角度旋转修正。

利用exif.js读取照片的拍摄信息,详见  http://code.ciaoca.com/javascript/exif-js/

这里主要用到Orientation属性。

Orientation属性说明如下:
旋转角度0°     参数1 
顺时针90°     6
逆时针90°     8
180°     3

接下来的代码是大佬写的,我用于学习借鉴:

下面代码原链接:https://blog.csdn.net/linlzk/article/details/48654835

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>图片上传</title>
    <script type="text/javascript" src="js/jquery-1.8.3.js"></script>
    <script type="text/javascript" src="js/uploadPicture/mobileBUGFix.mini.js" ></script>
    <script type="text/javascript" src="js/uploadPicture/uploadImage.js" ></script>
        <script type="text/javascript" src="js/exif.js" ></script>
</head>
<body>
    <div style="height: 50px; line-height: 50px;text-align: center;border-bottom: 1px solid #171E28;">
            上传图片:
            <input type="file" accept="image/*" id="uploadImage" capture="camera" onchange="selectFileImage(this);" />
        </div>
        <div style="margin-top: 10px;">
            <img alt="preview" src="" id="myImage"/>
        </div>
</body>
</html>

function selectFileImage(fileObj) {
    var file = fileObj.files['0'];
    //图片方向角 added by lzk
    var Orientation = null;
    
    if (file) {
        console.log("正在上传,请稍后...");
        var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
        if (!rFilter.test(file.type)) {
            //showMyTips("请选择jpeg、png格式的图片", false);
            return;
        }
        // var URL = URL || webkitURL;
        //获取照片方向角属性,用户旋转控制
        EXIF.getData(file, function() {
           // alert(EXIF.pretty(this));
            EXIF.getAllTags(this);
            //alert(EXIF.getTag(this, 'Orientation'));
            Orientation = EXIF.getTag(this, 'Orientation');
            //return;
        });
        
        var oReader = new FileReader();
        oReader.onload = function(e) {
            //var blob = URL.createObjectURL(file);
            //_compress(blob, file, basePath);
            var image = new Image();
            image.src = e.target.result;
            image.onload = function() {
                var expectWidth = this.naturalWidth;
                var expectHeight = this.naturalHeight;
                
                if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
                    expectWidth = 800;
                    expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
                } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
                    expectHeight = 1200;
                    expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
                }
                alert(expectWidth+','+expectHeight);
                var canvas = document.createElement("canvas");
                var ctx = canvas.getContext("2d");
                canvas.width = expectWidth;
                canvas.height = expectHeight;
                ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
                alert(canvas.width+','+canvas.height);
                
                var base64 = null;
                var mpImg = new MegaPixImage(image);
                    mpImg.render(canvas, {
                        maxWidth: 800,
                        maxHeight: 1200,
                        quality: 0.8,
                        orientation: Orientation
                    });
                    
                base64 = canvas.toDataURL("image/jpeg", 0.8);
                
                //uploadImage(base64);
                $("#myImage").attr("src", base64);
            };
        };
        oReader.readAsDataURL(file);
    }
}
 用到的第三方js文件:mobileBUGFix.mini.js

测试demo下载地址:

http://download.csdn.net/detail/linlzk/9127441

附上Exif.js说明

http://code.ciaoca.com/javascript/exif-js/

图片上传前 压缩,base64图片压缩 Exif.js处理ios拍照倒置等问题的更多相关文章

  1. 图片上传前预览、压缩、转blob、转formData等操作

    直接上代码吧: <template> <div> <div class="header">添加淘宝买号</div> <div ...

  2. 前端的图片压缩image-compressor(可在图片上传前实现图片压缩)

    https://www.imooc.com/article/40038 https://www.jianshu.com/p/3ce3e3865ae2 前端的图片压缩image-compressor(可 ...

  3. file标签 - 图片上传前预览 - FileReader & 网络图片转base64和文件流

    记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...

  4. input file实现多选,限制文件上传类型,图片上传前预览功能

    限制上传类型 & 多选:① accept 属性只能与 <input type="file" /> 配合使用.它规定能够通过文件上传进行提交的文件类型. ② mu ...

  5. html之file标签 --- 图片上传前预览 -- FileReader

    记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...

  6. 【转】html之file标签 --- 图片上传前预览 -- FileReader

    记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...

  7. hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images

    hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images, 本例子主要是使用HTML5 的File API,建立一個可存取到该file的url, 一个空的img标签,ID为img0,把 ...

  8. 【转】HTML5 jQuery图片上传前预览

    hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images,本例子主要是使用HTML5 的File API,建立一個可存取到该 file的url,一个空的img标签,ID为img0,把选 ...

  9. ASP.NET MVC图片上传前预览

    回老家过春节,大半个月,在家的日子里,吃好睡好,人也长了3.5Kg.没有电脑,没有网络,无需写代码,工作上相关的完全放下......开心与父母妻儿过个年,那样的生活令Insus.NET现在还在留恋.. ...

随机推荐

  1. vue中强制刷新的bug处理

    vue是单页面应用,跳转路由也是局部刷新,这里就拿后台管理系统而言,如果你的后台管理系统是左右布局,你不会遇到这样的问题,但是如果你的后台管理系统是上左右布局,你就会遇到这个问题,一级菜单在最上面,二 ...

  2. Struts2第三天

    ## Struts2第三天 ## ---------- **课程回顾:Struts2框架的第二天** 1. Servlet的API * ActionContext对象 * ServletActionC ...

  3. CSU 1838 Water Pump(单调栈)

    Water Pump [题目链接]Water Pump [题目类型]单调栈 &题解: 这题可以枚举缺口,共n-1个,之后把前缀面积和后缀面积用O(n)打一下表,最后总面积减去前缀的i个和后缀的 ...

  4. oracle中ddl的管理

    因为某些原因,Oracle的ddl权限不能开放给用户. 之前采取的方式是,创建用户的时候不为其赋予create table 的权限. 但是在使用过程中发现该用户还是拥有alter table的权限. ...

  5. 14. Longest Common Prefix(暴力循环)

    Write a function to find the longest common prefix string amongst an array of strings. If there is n ...

  6. Oracle10g 连接 sqlserver 在server2008r2 中连接 iis7 .net4.0

    一.做好了连接但是到了64位的server2008r2上就是不行,报错dns上不匹配.最后找到原因了 自己到c盘里面找32位的odbc管理工具然后建立连接,然后一切正常. 二.iis7 .net4.0 ...

  7. STL之stack容器

    1.stack容器 1) stack是堆栈容器,是一种“先进后出”的容器. 2)stack是简单地装饰deque容器而成为另外的一种容器. 3)头文件.#include <stack> 2 ...

  8. 文件、文件夹操作(I)

    遍历一个目录下的所有文件 首先我们获取用户文档目录路径 let manager = FileManager.default let urlForDocument = manager.urls(for: ...

  9. vue-cli 脚手架搭建

    1,下载node.js node.js 集成npm 管理器 2,打开命令行工具(win+R) node -v npm -v 出现对应版本号,则安装完成 3,配置代理信息 详见代理设定:https:// ...

  10. 做一次面向对象的体操:将JSON字符串转换为嵌套对象的一种方法

    背景与问题 在 <一个略复杂的数据映射聚合例子及代码重构> 一文中,将一个JSON字符串转成了所需要的订单信息Map.尽管做了代码重构和配置化,过程式的代码仍然显得晦涩难懂,并且客户端使用 ...