曾写过在前端把图片按比例压缩不失真上传服务器的前端和后台,可惜没有及时做总结保留代码,只记得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. iOS LeftMenu抽屉效果与ScrollView共存时的手势冲突

    公司有个项目,需要做左侧滑动,首页是ScrollView嵌套TableView.首页是一个ScrollView,所以当contentOffset是0.0的时候,无法直接滑动出抽屉效果,用户体验感非常差 ...

  2. iOS 新浪微博-2.0 搜索框/标题带箭头/下拉菜单

    不管是搜索框还是下拉菜单,我们都需要对背景的图片进行拉伸.定义一个Category分类对图片进行操作. UIImage+Effect.h #import <UIKit/UIKit.h> @ ...

  3. Cocos Creator iPhoneX适配的解决办法

    研究了5个小时的iPhoneX适配. 从catalog,storyboard,safearea等一系列文章中发现.如果我们想完全撑满全屏.那直接建一个storyboard就好了.但撑满全屏后,流海就是 ...

  4. node.js初识12

    1.express框架属于后端的框架 cnpm install --save express --save的作用是将下载的保存在package.json中 你可以点击http://www.expres ...

  5. sitecore系统教程之体验编辑器中创建一个项目

    您可以使用体验编辑器创建新项目并将其直接插入网页. 注意 如何在Sitecore中创建项目可能会有所不同,具体取决于您拥有的安全角色以及网站的设置方式. 要插入新项目: 在体验编辑器中,导航到要添加新 ...

  6. python os.path.splitext()

    # Split the file extension 可以把扩展名获取出来

  7. HashMap 和 ConcurrentHashMap比较

    基础知识: 1. ConcurrentHashMap: (JDK1.7) segment数组,分段锁:segment 内部是 HashEnty数组,类似HashMap: 统计长度的方法,先不加锁统计两 ...

  8. 转:"为自动填充列调整大小期间不能执行此操作"解决办法 .

    转载自:http://blog.csdn.net/zhxingway/article/details/5384690 今天在测试的时候,打开一个窗口突然发现出现以下错误,就算我在打开窗口那个按钮里面和 ...

  9. highchart 柱状图,列宽自适应(x轴是时间的特殊情况)

    1.柱子列宽自适属性: pointWidth:25, //柱子宽度,如果设定该值,则下面2个属性无效 pointPadding: 0.4,//每列之间的距离值,默认此值为0.1 groupPaddin ...

  10. sparkStreaming插入mysql 必须考虑到实时更新老的key

    原先使用批次提交更新 但数据库无变化,不得不一条一条的插入 公司数据量不大  还未做数据量大的测试 但实时更新是可以的 关键sql : insert into area_user_amt (date, ...