<!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('完成');
})
})