canvas图片上传剪裁

项目连续两次用到canvas啦!!什么ios拍照自动旋转的问题之类的(后续补上),然后到这次的图片上传剪裁。直接抄个dalao的代码,先用后写注释。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

<form name='test'>
    <input type="file" name='file'>
    <button id="clip">裁剪</button>
    <input type="submit" value="提交">
</form>
<canvas width="0" height="0"></canvas>
<script>
    var canvas = document.querySelector('canvas'),
        ctx = canvas.getContext('2d'),
        preview = new Image();
    document.test.file.addEventListener('change', function() {
        var fr = new FileReader();
        fr.onload = function() {
            preview.src = this.result;
            canvas.width = preview.width;
            canvas.height = preview.height;
            drawImage();
        };
        fr.readAsDataURL(this.files[0]);
    })
    function drawImage() {
        ctx.drawImage(preview, 0, 0); //把图片绘制到canvas上
    }
    document.test.addEventListener('submit', function(e) {
        e.preventDefault();
        var formData = new FormData(),
            xhr = new XMLHttpRequest(),
            mime = 'image/jpeg',
            dataUrl = canvas.toDataURL(mime, 0.8),  //取出base64
            data = atob(dataUrl.split(',')[1]),
            n = data.length,
            uInt8 = new Uint8Array(n),
            blob;
        while(n--) {
            uInt8[n] = data.charCodeAt(n);
        }
        blob = new Blob([uInt8.buffer], {type: mime});
        formData.append('file', blob, 'test.jpg');
        //xhr.open('post', './upload');
        console.log(formData);
        //xhr.send(formData);
    })

    var sPoint = {},
        ePoint = {};
    canvas.addEventListener('mousedown', function(e) {
        if(e.button === 0) {
            sPoint.x = e.offsetX;
            sPoint.y = e.offsetY;
            sPoint.drag = true;
        }
    });

    function drawCover() {
        ctx.save();
        ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.restore();
    }
    canvas.addEventListener('mousemove', function(e) {
        if(e.button === 0 && sPoint.drag) {var nPoint = {
            x: e.offsetX,
            y: e.offsetY
        };
            ctx.save();    //clip要通过restore回复
            ctx.clearRect(0, 0, canvas.width, canvas.height);    //画布全清
            drawImage();    //绘制底图
            drawCover();    //绘制阴影
            ctx.beginPath();    //开始路径
            ctx.rect(sPoint.x, sPoint.y, nPoint.x - sPoint.x, nPoint.y - sPoint.y);    //设置路径为选取框
            ctx.clip();    //截取路径内为新的作用区域
            drawImage();    //在选取框内绘制底图
            ctx.restore();    //恢复clip截取的作用范围
        }
    });

    canvas.addEventListener('mouseup', function(e) {
        if(e.button === 0) {
            sPoint.drag = false;
            ePoint.x = e.offsetX;
            ePoint.y = e.offsetY;
        }else if(e.button === 2) {
            restore();
        }
    });
    function restore() {
        sPoint = {};
        ePoint = {};
        drawImage();
    }

    document.addEventListener('contextmenu', function(e) {
        e.preventDefault();
        e.stopPropagation();
    });

    var clip = document.querySelector('#clip');
    clip.addEventListener('click', function(e) {
        e.preventDefault();    //阻止默认事件,不然会触发form的submit
        if(sPoint.x !== undefined && ePoint.x !== undefined) {
            var imgData = ctx.getImageData(sPoint.x, sPoint.y, ePoint.x - sPoint.x, ePoint.y - sPoint.y);    //把裁剪区域的图片信息提取出来
            ctx.clearRect(0, 0, canvas.width, canvas.height);    //清空画布
            canvas.width = Math.abs(ePoint.x - sPoint.x);    //重置canvas的大小为新图的大小
            canvas.height = Math.abs(ePoint.y - sPoint.y);
            ctx.putImageData(imgData, 0, 0);    //把提取出来的图片信息放进canvas中
            preview.src = canvas.toDataURL();    //裁剪后我们用新图替换底图,方便继续处理
            console.log(preview);//base 64
        }else {
            alert('没有选择区域');
        }
    });
</script>
</body>
</html>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值