头像图片上传可能会用到的图片压缩和图片旋转技术

业务背景

突然有一次搞活动,需要用户上传自己的自拍照,然后服务器端把头像做些特殊处理,这个时候可能会遇到的坑。

坑点二:人像是倒着的

如果用户直接采用摄像头拍照,这样的话获取到的照片可能会是倒着的,这样是影响业务的。

坑点一:图片过大

现在手机拍出来的照片,基本都是5M 以上的图片,对于上传压力太大了。

解决方案

人像是倒着的: exif.js 来解决

可以通过 exif.js 来获取图片的各种信息。

采用的是 exif-js 来获取图片基本信息

函数封装:

const getImgExif = function (file, callback) {
    
    
            $('#hideImg').attr('src', ''); // 先清空操作
            var reader = new FileReader();
            // 文件base64化,以便获知图片原始尺寸
            reader.onload = function (e) {
    
    
                var imgBase64 = e.target.result;
                $('#hideImg').attr('src', imgBase64);
                var $img = document.getElementById('hideImg');
                $img.onload = function () {
    
    
                    window.EXIF.getData($img, function () {
    
    
                        var orientation = EXIF.getTag(this, 'Orientation');
                        callback(false, orientation, imgBase64);
                    });
                };
            };
            reader.readAsDataURL(file);
        }

这样就可以获取到图片的orientation 属性了。

图片过大:canvas 压缩图片

可以利用 canvas 提供的 drawImage 方法来实现 图片的压缩。

核心方法

    /**
     *
     * @param imgBase64  图片的 base64
     * @param rotate 旋转角度
     * @param maxW 压缩的最大宽度
     * @param maxH 压缩的最大高度
     * @param callback 回调函数。
     */
    function rotateImg(imgBase64, rotate, maxW, maxH, callback) {
    
    
        var img = new Image();
        img.src = imgBase64;

        if (typeof maxW == 'function') {
    
    
            callback = maxW;
            maxW = null;
            maxH = null;
        }

        if (rotate) {
    
    
            if (rotate !== '90' && rotate !== '-90' && rotate !== '180') {
    
    
                rotate = null;
            }
        }

        img.onload = function (ev) {
    
    
            var originWidth = this.width;
            var originHeight = this.height;
            var targetWidth = originWidth;
            var targetHeight = originHeight;

            var maxWidth = maxW || 750, maxHeight = maxH || 750;

            if (originWidth > maxWidth || originHeight > maxHeight) {
    
    
                if (originWidth / originHeight > maxWidth / maxHeight) {
    
    
                    targetWidth = maxWidth;
                    targetHeight = Math.round(maxWidth * (originHeight / originWidth));
                } else {
    
    
                    targetHeight = maxHeight;
                    targetWidth = Math.round(maxHeight * (originWidth / originHeight));
                }
            }

            var canvas = document.createElement('canvas');
            var context = canvas.getContext('2d');
            canvas.width = targetWidth;
            canvas.height = targetHeight;
            context.clearRect(0, 0, targetWidth, targetHeight);
            context.drawImage(img, 0, 0, originWidth, originHeight, 0, 0, targetWidth, targetHeight);
            var dataUrl = canvas.toDataURL("image/jpeg");

            if (rotate) {
    
    
                var angle = 0;
                var canvas2 = document.createElement('canvas');
                var context2 = canvas2.getContext('2d');
                canvas2.width = targetWidth;
                canvas2.height = targetHeight;

                var _setting = {
    
    
                    dx: 0,
                    dy: 0,
                    dw: 0,
                    dh: 0,
                    transX: 0,
                    transY: 0
                };
                var scale = 0;
                if (rotate === '180') {
    
    
                    angle = Math.PI;
                    _setting.dw = targetWidth;
                    _setting.dh = targetHeight;
                    context2.translate(targetWidth, targetHeight);
                    context2.rotate(angle);
                    context2.translate(0, 0);
                }
                else {
    
    
                    if (rotate === '90') {
    
    
                        angle = 90 * (Math.PI / 180);
                    }
                    else if (rotate === '-90') {
    
    
                        angle = -90 * (Math.PI / 180);
                    }
                    _setting.transX = parseFloat(targetHeight / 2);
                    _setting.transY = parseFloat(targetWidth / 2);
                    _setting.dw = targetHeight;
                    scale = targetWidth / targetHeight;
                    _setting.dh = parseFloat(_setting.dw / scale);
                    _setting.dy = (targetWidth - _setting.dh) / 2;
                    context2.translate(_setting.transX, _setting.transY);
                    context2.rotate(angle);
                    context2.scale(scale, scale);
                }

                /**
                 * ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
                 *
                 * image: 可以是一个image ,或者一个canvas
                 * sx: 在画布所绘制图片本身的x轴的距离
                 * sy: 在画布所绘制图片本身y轴的距离
                 * sWidth:表示所绘制图片的宽度范围,一般默认是图片的完整大小。也可以是部分绘制。
                 * sHeight:表示所绘制图片的高度范围,一般默认是图片的完整大小。也可以是部分绘制。
                 * dx:表示在画布x轴的坐标值
                 * dy:表示在画布y轴的坐标值
                 * dWidth: 在画布绘制的宽度
                 * dHeight:在画布绘制的长度
                 */
                context2.drawImage(canvas, 0, 0, targetWidth, targetHeight, _setting.dx - _setting.transX, _setting.dy - _setting.transY, _setting.dw, _setting.dh);
                dataUrl = canvas2.toDataURL("image/jpeg");
            }
            callback(dataUrl);
        };
    }

demo

demo地址:canvas-rotate-image
demo2地址:上传头像
github地址:github

猜你喜欢

转载自blog.csdn.net/wancheng815926/article/details/105601644
今日推荐