zoukankan      html  css  js  c++  java
  • JS实现图片base64转blob对象,压缩图片,预览图片,图片旋转到正确角度

    base64转blob对象

    /** 将base64转换为文件对象
     *  @param {String} base64 base64字符串
     * */
    var convertBase64ToBlob = function(base64){
        var base64Arr = base64.split(',');
        var imgtype = '';
        var base64String = '';
        if(base64Arr.length > 1){
            //如果是图片base64,去掉头信息
            base64String = base64Arr[1];
            imgtype = base64Arr[0].substring(base64Arr[0].indexOf(':')+1,base64Arr[0].indexOf(';'));
        }
        // 将base64解码
        var bytes = atob(base64String);
        //var bytes = base64;
        var bytesCode = new ArrayBuffer(bytes.length);
         // 转换为类型化数组
        var byteArray = new Uint8Array(bytesCode);
        
        // 将base64转换为ascii码
        for (var i = 0; i < bytes.length; i++) {
            byteArray[i] = bytes.charCodeAt(i);
        }
       
        // 生成Blob对象(文件对象)
        return new Blob( [bytesCode] , {type : imgtype});
    };

    压缩图片

    /** 压缩图片
     * @param {Object} file 上传对象files[0]
     * @param {Object} options 压缩设置对象
     * @param {Function} callback 回调函数
     * @result {Object} 返回blob文件对象
     * */
    var compressImg = function(file,options,callback){
        var self = this;
        var imgname = file.name;
        var imgtype = (imgname.substring(imgname.lastIndexOf('.') + 1)).toLowerCase();
        if(imgtype == 'jpg' || imgtype == 'jpeg'){
            imgtype = 'image/jpeg';
        }else{
            imgtype = 'image/png';
        }
        // 用FileReader读取文件
        var reader = new FileReader();
        // 将图片读取为base64
        reader.readAsDataURL(file);
        reader.onload = function(evt){
            var base64 = evt.target.result;
            // 创建图片对象
            var img = new Image();
            // 用图片对象加载读入的base64
            img.src = base64;
            img.onload = function () {
                var that = this,
                    canvas = document.createElement('canvas'),
                    ctx = canvas.getContext('2d');
                canvas.setAttribute('width', that.width);
                canvas.setAttribute('height', that.height);
                // 将图片画入canvas
                ctx.drawImage(that, 0, 0, that.width, that.height);
                
                // 压缩到指定体积以下(M)
                if(options.size){
                    var scale = 0.9;
                    (function f(scale){
                        if(base64.length / 1024 / 1024 > options.size && scale > 0){
                            base64 = canvas.toDataURL(imgtype, scale);
                            scale = scale - 0.1;
                            f(scale);
                        }else{
                            callback(base64);
                            
                        }
                    })(scale); 
                } else if(options.scale){
                    // 按比率压缩
                    base64 = canvas.toDataURL(imgtype, options.scale);
                    callback(base64);
                }
                
            }
        }
    };

    图片预览

    /**
     * 图片预览
     * @param {Object} $fileInput 文件上传file
     * @param {Object} $previewImg 预览图片的image元素
     */
    function previewImg($fileInput, $previewImg) {
        $fileInput.onchange = function ($event) {
            var $target = $event.target;
            if ($target.files && $target.files[0]) {
                var reader = new FileReader();
                reader.onload = function(evt){
                    $previewImg.src = evt.target.result;
                }
                reader.readAsDataURL($target.files[0]);
            }
        }
    }

    详细图片预览可参考地址:《搞清Image加载事件(onload)、加载状态(complete)后,实现图片的本地预览,并自适应于父元素内(完成)

    图片旋转到正确的角度(验证可行)

    /**
     * 将图片旋转到正确的角度
     * (解决移动端上传的图片角度不正确的问题)
     * (旋转后返回的是base64,可以参照本目录下的convertBase64ToBlob.js,将base64还原为file input读取得到的文件对象)
     * @param {Dom Object} $fileInput 文件上传输入框
     * @param {Function} callback 旋转完成后的回调函数
     */
    function resetImgOrientation($fileInput, callback) {
        // 绑定change事件
        $fileInput.onchange = function ($event) {
            var $target = $event.target;
            if ($target.files && $target.files[0]) {
                // 获取图片旋转角度
                getOrientation($target.files[0], function (orientation) {
                    var reader = new FileReader();
                    reader.readAsDataURL($target.files[0]);
                    reader.onload = function(evt){
                        var base64 = evt.target.result;
                        // 将图片旋转到正确的角度
                        resetOrientation(base64, orientation, function (resultBase64) {
                            callback(resultBase64);
                        });
                    }
                });
            }
        }
    }
    
    // 获取图片旋转的角度
    function getOrientation(file, callback) {
        var reader = new FileReader();
        reader.readAsArrayBuffer(file);
        reader.onload = function(e) {
            var view = new DataView(e.target.result);
            if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
            var length = view.byteLength, offset = 2;
            while (offset < length) {
                var marker = view.getUint16(offset, false);
                offset += 2;
                if (marker == 0xFFE1) {
                    if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1);
                    var little = view.getUint16(offset += 6, false) == 0x4949;
                    offset += view.getUint32(offset + 4, little);
                    var tags = view.getUint16(offset, little);
                    offset += 2;
                    for (var i = 0; i < tags; i++)
                        if (view.getUint16(offset + (i * 12), little) == 0x0112)
                            return callback(view.getUint16(offset + (i * 12) + 8, little));
                }
                else if ((marker & 0xFF00) != 0xFF00) break;
                else offset += view.getUint16(offset, false);
            }
            return callback(-1);
        };
    }
    // 将图片旋转到正确的角度
    function resetOrientation(srcBase64, srcOrientation, callback) {
        var img = new Image();
        img.onload = function() {
            var width = img.width,
                height = img.height,
                canvas = document.createElement('canvas'),
                ctx = canvas.getContext("2d");
            // set proper canvas dimensions before transform & export
            if ([5,6,7,8].indexOf(srcOrientation) > -1) {
                canvas.width = height;
                canvas.height = width;
            } else {
                canvas.width = width;
                canvas.height = height;
            }
            // transform context before drawing image
            switch (srcOrientation) {
                case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
                case 3: ctx.transform(-1, 0, 0, -1, width, height ); break;
                case 4: ctx.transform(1, 0, 0, -1, 0, height ); break;
                case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
                case 6: ctx.transform(0, 1, -1, 0, height , 0); break;
                case 7: ctx.transform(0, -1, -1, 0, height , width); break;
                case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
                default: ctx.transform(1, 0, 0, 1, 0, 0);
            }
            // draw image
            ctx.drawImage(img, 0, 0);
            // export base64
            callback(canvas.toDataURL('image/jpeg'));
        };
        img.src = srcBase64;
    };

    参考地址:

    file上传图片,base64转换、压缩图片、预览图片、将图片旋转到正确的角度
    H5图片压缩与上传

    Accessing JPEG EXIF rotation data in JavaScript on the client side

  • 相关阅读:
    小结 编程练习 制作新按钮,“新窗口打开网站” ,新窗口打开时弹出确认框,是否打开,通过输入对话框,打开的窗口要求,宽400像素,高500像素,无菜单栏、无工具栏。
    关闭窗口(window.close)
    打开新窗口(window.open) open() 方法可以查找一个已经存在或者新建的浏览器窗口。 语法: window.open([URL], [窗口名称], [参数字符串])
    提问(prompt 消息对话框)用于询问一些需要与用户交互的信息。弹出消息对话框(包含一个确定按钮、取消按钮与一个文本输入框)
    确认(confirm 消息对话框)语法:confirm(str); 消息对话框通常用于允许用户做选择的动作,如:“你对吗?”等。弹出对话框(包括一个确定按钮和一个取消按钮)
    警告(alert 消息对话框) 如果你不点击“确定”,就不能对网页做任何操作,这个小窗口就是使用alert实现的
    Socket的3次握手链接与4次断开握手
    大型电子商务网站架构之--分布式可扩展数据库架构
    程序员成长历程的四个阶段
    盘点 Github 所用到的开源项目
  • 原文地址:https://www.cnblogs.com/moqiutao/p/8657926.html
Copyright © 2011-2022 走看看