canvas压缩图片上传

15 篇文章 0 订阅
4 篇文章 0 订阅

图片预览

使用html5中FileReader读取文件base64信息

var input = document.querySelector('input');
var preview = document.querySelector('.preview');

input.onchange = function(){
    var file = input.files[0];
    //创建一个文件读取者
    var reader = new FileReader();
    //读取文件base64信息
    reader.readAsDataURL(file);
    //读取成功
    reader.onload = function(e){
        var img = new Image();
        img.src = e.target.result;
        preview.appendChild(img)
  }
}

效果图

原生XMLHttpRequest上传文件

html代码

<input type="file">
<button disabled="disabled">确认上传</button>
<div class="preview"><img src="" alt=""></div>
<div class="show"></div>
<script>
    var input = document.querySelector('input');//文件表单元素
    var btn = document.querySelector('button');//上传按钮
    var preview = document.querySelector('.preview > img');//图片预览区
    var show = document.querySelector('.show');//图片显示区

    input.onchange = function(){
        var file = this.files[0];
        //创建FileReader对象读取文件base64信息
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e){
            preview.src = e.target.result;//预览图
        }
        btn.removeAttribute('disabled');//上传按钮可点击
        //点击上传
        btn.onclick = function(){
            var xhr = new XMLHttpRequest();
            //创建formData对象
            var formData = new FormData();
            //加入上传文件数据
            formData.append('file', file);
            xhr.open('post', '/upload', true);
            xhr.onreadystatechange = function(){
                //文件上传成功
                if(xhr.readyState === 4 && xhr.status === 200){
                    //后台返回数据,包含文件存储路径
                    var resObj = JSON.parse(xhr.responseText);
                    preview.src = '';//清除预览图
                    input.value = '';//清空input值
                    btn.setAttribute('disabled', 'disabled');//上传按钮不可点击
                    //图片显示区
                    var img = new Image();
                    img.src = resObj.filePath;
                    img.style.display = 'block';
                    show.appendChild(img);
                }
            }
            //上传文件
            xhr.send(formData);
        }
    }
        
</script>

koa2后台代码,使用koa-body中间件

const Router = require('koa-router');
const router = new Router();
const koaBody = require('koa-body');
const fs = require('fs');

router.use(koaBody({
    multipart: true,
    formidable: {
        maxFileSize: 200 * 1024 * 1024 // 设置上传文件大小最大限制,默认2M
    }
}));

router.post('/', async ctx => {
    try{
        let file = ctx.request.body.files.file; // 获取上传文件
        let reader = fs.createReadStream(file.path); // 创建可读流
        let ext = file.name.split('.').pop(); // 获取上传文件扩展名
        let filePath = `public/upload/${Date.now().toString()}.${ext}`;//存储路径
        let writer = fs.createWriteStream(filePath); // 创建可写流
        reader.pipe(writer); // 可读流通过管道写入可写流
        return ctx.body = {
            msg: '上传成功',
            filePath: filePath.slice(7)
        }
    }catch(error){
        return;
    }
})


module.exports = router;

用canvas将图片进行裁切再上传

思路是先判断原文件大小,然后用canvas裁切,然后canvas转成dataURL,再将dataURL转成blob对象,然后上传

dataURL转blob方法

//dataUrl转blob
function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}

canvas裁切

//处理图片
function drawImg(file){
    return new Promise((resolve, reject) => {
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e){
            let imgSrc = e.target.result;
            let img = new Image();
            img.src = imgSrc;
            img.onload = function(){
                console.log(this.width, this.height);
                let originWidth = this.width;   //图片原宽度
                let originHeight = this.height;
                let targetWidth = originWidth;  //图片裁剪目标宽度
                let targetHeight = originHeight;
                let quality = 0.8;     //图片质量0-1之间(默认0.92)
                if(originWidth < 2000 && file.size >= 1*1024*1024){     //如果图片宽度小于2000px且大小大于1m
                    quality = 0.6;
                }else if(originWidth >= 2000){      //如果图片宽度大于2000px
                    targetWidth = Math.round(originWidth * 0.6);
                    targetHeight = Math.round(originHeight * 0.6);
                    quality = 0.6;
                }
                let canvas = document.createElement('canvas');
                let ctx = canvas.getContext('2d');
                //画板大小
                canvas.width = targetWidth;
                canvas.height = targetHeight;
                //清除画板
                ctx.clearRect(0, 0, targetWidth, targetHeight);
                //绘画
                ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
                //canvas转dataURL
                let dataUrl = canvas.toDataURL(file.type, quality);
                let blob = dataURLtoBlob(dataUrl);    //得到blob对象
                let formData = new FormData();
                formData.append('file', blob, file.name);
                resolve(formData);
            }
        }
    })
}

参考文章

参考文章

参考文章

参考文章

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值