JS使用canvas操作压缩图片

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS使用canvas操作压缩图片相关的知识,希望对你有一定的参考价值。

1.使用input标签添加图片文件。

<input type="file" name="upload_photo" id="upload_photo" accept="image/jpg,image/jpeg,image/png" value=‘upload now‘>//使用accept限定文件类型

2.监听input的change事件,获取文件内容

  

                $(‘#upload_photo‘).on(‘change‘, function() {//监听change事件
                    var file = $(‘#upload_photo‘)[0].files[0];//获取到文件内容
                    if (_.isUndefined(file))
                        return;
                    self.toggleLoading(true);

                    if (self.app.isios()) {//判断当前是否为IOS系统,如果是,需要使用EXIF插件判断照片的方向
                        EXIF.getData(file, function() {
                            self.app.ort = EXIF.getTag(this, ‘Orientation‘);
                            var url = self.createObjectURLfun(file);//使用window.webkitURL.createObjectURL生成图片的URL
                            self.app.photoData = url;
                            self.setPhoto();
                        });
                    } else {
                        var url = self.createObjectURLfun(file);
                        self.app.photoData = url;
                        self.setPhoto();
                    }

                })

3.使用Image对象加载url内容

  

                this._img = new Image();
                this.toggleLoading(true);
                this._img.onload = function() {
                    console.log(‘img loaded ‘ + self._img.width + ‘x‘ + self._img.height);
                    self.initCanvas();//加载完成后初始化canvas
                    self.toggleLoading(false);
                };
                this._img.onerror = function() {
                    self.toggleLoading(false);
                    AlertMsg(‘加载图片失败...‘);
                };
                $(‘.change_img_btn‘).on(‘click‘, function() {
                    console.log(‘change_img‘);
                    $(‘#upload_photo‘).click();
                });

4.初始化canvas

  

          this._canvas = document.getElementById(‘img_canvas‘);
                this._cxt = this._canvas.getContext("2d");
                this._canvasW = this._canvas.width;
                this._canvasH = this._canvas.height;
                var x, y, width, height;
         //使图片居中显示
if (this._img.width > this._canvasW || this._img.height > this._canvasH) { //宽图片 if (this._img.width > this._img.height) { x = 0; width = this._canvasW; height = (this._canvasW / this._img.width) * this._img.height; y = (this._canvasH - height) / 2; } else { //长图片 y = 0; height = this._canvasH; width = (this._canvasH / this._img.height) * this._img.width; x = (this._canvasW - width) / 2; } } else { x = (this._canvasW - this._img.width) / 2; y = (this._canvasH - this._img.height) / 2; width = this._img.width; height = this._img.height; } var preArg = this._drawArg || {}; this._drawArg = {}; this._drawArg.x = x; this._drawArg.y = y; this._drawArg.width = width; this._drawArg.height = height; this._drawArg.dx = 0; this._drawArg.dy = 0; this._drawArg.scale = 1;
          //IOS系统下,根据图片方向进行旋转和移动 if (!!this.app.ort) { switch (this.app.ort) { case 3: this._cxt.rotate(180 * Math.PI / 180); this._cxt.translate(-this._canvasW, -this._canvasH); break; case 6: this._cxt.rotate(90 * Math.PI / 180); this._cxt.translate(0, -this._canvasH); break; case 8: this._cxt.rotate(-90 * Math.PI / 180); this._cxt.translate(-this._canvasW, 0); break; case 1: default: break; } } this._cxt.clearRect(-preArg.dx - this._canvasW, -preArg.dy - this._canvasH, this._canvasW * 3, this._canvasH * 3); this.drawCanvas();

 

5.通过覆盖在canvas上的DIV来操作,初始化div的事件监听

translateCanvas: function(dx, dy) {
                if (!!this.app.ort) {
                    var tmpX = dx;
                    var tmpY = dy;
                    switch (this.app.ort) {
                        case 3:
                            dx = -tmpX;
                            dy = -tmpY;
                            break;
                        case 6:
                            dx = tmpY;
                            dy = -tmpX;
                            break;
                        case 8:
                            dx = -tmpY;
                            dy = tmpX;
                            break;
                        case 1:
                        default:
                            break;
                    }

                }

                this._drawArg.dx += dx;
                this._drawArg.dy += dy;
                this._cxt.clearRect(-dx - this._canvasW, -dy - this._canvasH, this._canvasW * 3, this._canvasH * 3);
                this._cxt.translate(dx, dy);
                this.drawCanvas();
            },
            scaleCanvas: function(scale) {
                this._drawArg.scale *= scale;
                this._cxt.clearRect(-this._canvasW, -this._canvasH, this._canvasW * 3, this._canvasH * 3);
                this._cxt.scale(scale, scale);

                var deltaX = (scale - 1) * this._canvasW / 2;
                var deltaY = (scale - 1) * this._canvasH / 2;
                this._cxt.translate(-deltaX, -deltaY);
                this._drawArg.dx -= deltaX;
                this._drawArg.dy -= deltaY;

                this.drawCanvas();
            },
            initImageOperate: function() {
                var self = this;
                var $el = $(‘.img_operate‘);
                var preX = 0,
                    preY = 0,
                    preDistance = 0,
                    lastIsScale = false;
                $el.on(‘touchstart‘, function(evt) {
                    evt.preventDefault();
                    console.log(evt.targetTouches.length)
                    if (evt.targetTouches.length == 1) {
                        preX = evt.targetTouches[0].clientX;
                        preY = evt.targetTouches[0].clientY;
                    } else if (evt.targetTouches.length == 2) {
                        preDistance = Math.sqrt(Math.pow(evt.targetTouches[0].clientX - evt.targetTouches[1].clientX, 2) + Math.pow(evt.targetTouches[0].clientY - evt.targetTouches[1].clientY, 2));
                        // console.log(‘preDistance ‘ + preDistance);
                    }
                });

                $el.on(‘touchmove‘, function(evt) {
                    evt.preventDefault();
                    // console.log(evt.changedTouches.length);
                    if (evt.targetTouches.length == 1) {
                        if (lastIsScale) {
                            lastIsScale = false;
                            preX = evt.changedTouches[0].clientX;
                            preY = evt.changedTouches[0].clientY;
                        } else {
                            var dx = evt.changedTouches[0].clientX - preX;
                            var dy = evt.changedTouches[0].clientY - preY;
                            self.translateCanvas(dx, dy);
                            preX = evt.changedTouches[0].clientX;
                            preY = evt.changedTouches[0].clientY;
                        }

                    } else if (evt.targetTouches.length == 2) {
                        var curDistance = Math.sqrt(Math.pow(evt.changedTouches[0].clientX - evt.changedTouches[1].clientX, 2) + Math.pow(evt.changedTouches[0].clientY - evt.changedTouches[1].clientY, 2));
                        self.scaleCanvas(curDistance / preDistance);
                        // console.log(‘curDistance ‘ + curDistance);
                        preDistance = curDistance;
                        lastIsScale = true;
                    }

                });

                $el.on(‘touchend‘, function(evt) {

                });
            },

6.编辑完成后使用canvas的接口生成base64编码的图片数据

  

self._canvas.toDataURL(‘image/png‘)

 

以上是关于JS使用canvas操作压缩图片的主要内容,如果未能解决你的问题,请参考以下文章

前端js实现canvas压缩图片并上传

Js利用Canvas实现图片压缩

canvas图片压缩,局部放大,像素处理

前端JS利用canvas的drawImage()对图片进行压缩

canvas压缩裁切图片和格式转换的方法

js canvas压缩图片和jQuery ajax上传图片简单demo