js图片canvas压缩后端接收

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <input type="file" id="file">
  <img alt="暂无" srcset="" id="img1">
  <div>
    <canvas id="canvas"></canvas>
  </div>
  <button id="but">压缩</button>
  <p>压缩之后</p>
  <img alt="暂无" srcset="" id="img2">
  <img alt="" id="imgafter">
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script>
    let file = document.getElementById('file')
    let img1 = document.getElementById('img1')
    let img2 = document.getElementById('img2')
    let canvas = document.getElementById('canvas') // 设置画布的属性
    // canvas.width = 130
    // canvas.height = 130
    let context = canvas.getContext('2d') // 绘制图片的方法
    file.onchange = async function (e) {
    
     // 等待图片加载完成 然后获取信息
      let read = new FileReader()
      console.log(e.target.files[0])
      img1.src = URL.createObjectURL(new Blob([e.target.files[0]]))
      img1.onload = await function () {
    
     // 拿图片宽高
        if (e.target.files[0].size / 1024 > 100) {
    
     // 做图片大小处理 因为有些大图 压缩反而大了
          canvas.width = img1.width / 2
          canvas.height = img1.height / 2 // 比例自己定 不损坏图片 就行 但不能保留原来的样子的
        } else {
    
    
          canvas.width = img1.width
          canvas.height = img1.height
        }
      }
      read.readAsDataURL(new Blob([e.target.files[0]])) // 转base64
      read.onload = function (b) {
    
    
        img2.src = b.target.result
        img2.onload = function () {
    
    
          let img3 = new Image(img2.width, img2.height)
          img3.src = b.target.result
          context.drawImage(img3, 0, 0, img2.width, img2.height)
          canvas.toBlob((blob) => {
    
    
            console.log(blob)
            const from = new FormData()
            from.append('file', blob)
            console.log(from.get('file'))
            axios({
    
    
              url: 'http://localhost:4000/upla?' + 'name=' + e.target.files[0].name,
              method: 'post', // name 是图片名字的拼接 用于 后端接收 改变名字
              data: from // 因blob二进制流 不具有file文件信息了 所以 需要这样
            }).then(res => {
    
    
              console.log(res)
            })
            document.getElementById('imgafter').src = URL.createObjectURL(new Blob([blob], {
    
    
              type: e.target.files[0].type
            }))
          }, e.target.files[0].type)
          // var base64 = canvas.toDataURL(e.target.files[0].type,0.1); //第二个参数为压缩的比例,越小越模糊。0-1
          // console.log(new Blob([base64],{type:e.target.files[0].type}))
          // document.getElementById('imgafter').src = base64
          // 压缩 base64 更新 于 2021-2-7
          var base64 = canvas.toDataURL(e.target.files[0].type, 0.5); //第二个参数为压缩的比例,越小越模糊。0-1
          document.getElementById('imgafter').src = base64
          const app = new FormData()
          function dataURLtoFile(dataurl, filename) {
    
    
            var arr = dataurl.split(',');
            console.log(arr)
            var mime = arr[0].match(/:(.*?);/)[1]; 
            // base64 两部分组件 type前缀 与 btoa编码字符串
            var bstr = atob(arr[1]); 
            // atob() 方法用于解码 base-64 编码的字符串。base-64 编码使用方法是 btoa()
            var n = bstr.length; //      
            var u8arr = new Uint8Array(n);
             // 指定解码base64字符串的编码方式 转为8进制的字节数组 指定长度 
            // 只有一个参数 可以是长度 也可以是buffer二进制流 
            while (n--) {
    
    
              u8arr[n] = bstr.charCodeAt(n); // 一个个字符串的转化
            }
            console.log(u8arr) 
            //转换成file对象
            return new File([u8arr], filename, {
    
     
              // base64 两部分组成 type前缀 与 btoa编码字符串 
              // atob转码(btoa编码字符串) 循环字符串   插入u8arr八进制的字节数组
              type: mime
            });
            //转换成成blob对象
            //return new Blob([u8arr],{type:mime});
            // 总结 图片 采用 blob file 都 由 base64 八进制字节数组  
            // blob 为 base64 采用 btoa 读取字节数组 输出结果  个人 想法
          }
          console.log(dataURLtoFile(base64, e.target.files[0].name))

          app.append('file', dataURLtoFile(base64, e.target.files[0].name))
          axios({
    
    
            url: 'http://localhost:4000/upla?' + 'name=' + e.target.files[0].name,
            method: 'post',
            data: app
          }).then(res => {
    
    
            console.log(res)
          })
        }
        
      }

    }
  </script>
</body>

</html>

后端核心

var express = require('express')
var app = express()
var path = require('path')
var fs = require('fs')
var multiparty = require('multiparty')
app.use('/css',express.static('./public/css'))
app.use('/js',express.static('./public/js'))
app.use('/img',express.static('./public/img'))
app.use('/fonts',express.static('./public/fonts'))
app.all('*', function(req, res, next) {
    
    
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "token,name,age,Origin, X-Requested-With, Content-Type, Accept, Authorization");
  res.header('X-Powered-By','123')
  res.header('Access-Control-Expose-Headers','setcookie,X-Powered-By') // 暴露响应头
  next();
});
app.use('/upla',(req,res)=>{
    
     // 接收文件上传
  let form = new multiparty.Form({
    
    
    uploadDir: './public' //指定上传的文件路径
  });
  let imgName = req.query.name
  form.parse(req, (err, field, files) => {
    
    
    files && files.file.map(x => {
    
     // 必须这样写
      let img = imgName || x.originalFilename
      fs.rename(x.path, './public/' + img, () => {
    
    
        console.log('改名')
      })
    })
    res.end(JSON.stringify({
    
    
      ok: 200
    }))
  })
  form.on('field', (name, value) => {
    
    
    // name:字段名
    // value:值
    console.log('数据:', name, value);

  })
  //接收文件数据
  form.on('file', (name, file) => {
    
    
    console.log('文件:', name, file);
  })
  //表单解析完成
  form.on('close', () => {
    
    
    console.log('完成');
  })
})

猜你喜欢

转载自blog.csdn.net/qq_43505774/article/details/113725539