曾写过在前端把图片按比例压缩不失真上传服务器的前端和后台,可惜没有及时做总结保留代码,只记得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. FlexViewer之整体框架解析

    参考:https://www.cnblogs.com/naaoveGIS/p/3915912.html GIS之家:https://xiaozhuanlan.com/gishome 小专栏:https ...

  2. spring之文件上传

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  3. mysql数据库表设计小数类型

    float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位)double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E308(15个有效 ...

  4. NHibernate初学者指南系列文章导航

    NHibernate初学者指南系列文章导航   前面的话 经过三个多周的时间,终于将这个系列完成了,谢谢大家的关注和支持,有很多不足之处还望大家包涵. 本系列参考的书籍为NHibernate 3 Be ...

  5. mongodb对数组元素及内嵌文档进行增删改查操作(转)

    from:https://my.oschina.net/132722/blog/168274 比如我有一个user类,他包含一个标签属性,这个标签是一个数组,数组里面的元素是内嵌文档,格式如下: &l ...

  6. rpgmakermv(10) GraphicalDesignMode

    插件地址:https://github.com/triacontane/RPGMakerMV/blob/master/GraphicalDesignMode.js 原文: メニュー画面や戦闘画面など各 ...

  7. asp.net GridView增加删除功能

    protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)    {        string id ...

  8. Quick-Cocos2d-x文件结构分析

    在上一章我们讲过了Quick-Cocos2d-x中的环境搭建,这章我们分析下quick中的文件结构吧!打开quick的文件夹,可以看到如下的这些目录和文件: bin:存放各种与引擎相关的脚本 comp ...

  9. Qt 添加 QtNetwork 库文件

    Qt应用程序默认没有加QtNetwork库.如下图: 在开发过程中,因处理业务需要手动添加QtNetwork库.根据常见情况分为以下两种: [1]若使用QTCreator开发程序 在工程的pro文件中 ...

  10. eclipse xml 文件添加注解快捷键

    eclipse xml 文件注解快捷键: <!--  --> Ctrl + shift + / 添加注解 Ctrl + shift + \ 取消注解