图片预览
使用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);
}
}
})
}