轮播图组件
轮播图滑动:github.com/surmon-chin…
演示地址:3.swiper.com.cn/demo/index.…
图片压缩和上传
参考链接:
www.zhangxinxu.com/study/20170…
前端JS压缩图片并上传:segmentfault.com/a/119000001…
ios上传压缩图片发生90度旋转:github.com/lin-xin/blo…
流程图:
图片压缩上传,安卓和ios,解决旋转综合代码:
<style lang="scss" scoped>
.image-upload {
position: relative;
display: inline-block;
.camera {
display: inline-block;
width: 0.4rem;
height: 0.4rem;
vertical-align: middle;
}
.upload {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
opacity: 0;
}
}
</style>
<template>
<div class="image-upload">
<img class="camera" src="https://img.meituan.net/codeman/343cc626b6015f355003bc3268c233c26495.png">
<!--<input type="file" class="upload" accept="image/*" @change="upload" multiple>-->
<input type="file" accept='.png, .jpg, .jpeg' class="upload" @change="upload">
</div>
</template>
<script>
import {Toast, Indicator} from 'mint-ui';
import Exif from 'exif-js';
export default {
props: {
uploadapi: {
type: null,
required: true
}
},
methods: {
upload () {
const that = this;
let fileinput = this.$el.querySelector('.image-upload input[type=file]');
let orientation = null;
let file = fileinput.files[0];
if (/image/.test(file.type)) {
that.$emit('upload-doing');
Exif.getData(file, function(){
orientation = Exif.getTag(this, 'Orientation');
that.compressImage(orientation, file, (file)=>{
const formData = new FormData();
formData.append('file', file);
that.uploadapi(formData).then(res => {
that.$emit('upload-success', res.data);
fileinput.value = '';
}).catch(err => {
that.uploadapi(formData).then(resE => {
that.$emit('upload-error', resE.data);
fileinput.value = '';
}).catch(errE => {
Toast(errE.data.message);
});
});
});
});
} else {
Toast('请上传图片');
}
},
compressImage (orientation, file, success, error) {
// 图片小于500k不压缩
if (file.size < Math.pow(512, 2)) {
return success(file);
}
const name = file.name; //文件名
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
const src = e.target.result;
const img = new Image();
img.src = src;
img.onload = (e) => {
const maxW = 2500;
const maxH = 2500;
const w = img.width;
const h = img.height;
let targetW = w;
let targetH = h;
if (w>maxW || h>maxH) {
if (w/h > maxW/maxH) {
targetW = maxW;
targetH = Math.round(maxW*(h/w));
} else {
targetH = maxH;
targetW = Math.round(maxH*(w/h));
}
}
const quality = 0.5; // 默认图片质量为0.92,这个值的区间0-1,值越小,图片越模糊,压缩力度越大
//生成canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 创建属性节点
const anw = document.createAttribute("width");
anw.nodeValue = targetW;
const anh = document.createAttribute("height");
anh.nodeValue = targetH;
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
//铺底色 PNG转JPEG时透明区域会变黑色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, targetW, targetH);
// 图片压缩上传ios旋转fix
if (orientation && orientation!== 1) {
switch(orientation){
case 6:
canvas.width = targetH;
canvas.height = targetW;
ctx.rotate(Math.PI / 2);
ctx.drawImage(img, 0, -targetH, targetW, targetH);
break;
case 3:
ctx.rotate(Math.PI);
ctx.drawImage(img, -targetW, -targetH, targetW, targetH);
break;
case 8:
canvas.width = h;
canvas.height = w;
ctx.rotate(3 * Math.PI / 2);
ctx.drawImage(img, -targetW, 0, targetW, targetH);
break;
}
} else {
ctx.drawImage(img, 0, 0, targetW, targetH);
}
// quality值越小,所绘制出的图像越模糊
const base64 = canvas.toDataURL('image/jpeg', quality); //图片格式jpeg或webp可以选0-1质量区间
// console.log('base64', base64);
// 返回base64转blob的值
console.log(`原图${(src.length/1024).toFixed(2)}kb`, `新图${(base64.length/1024).toFixed(2)}kb`);
//去掉url的头,并转换为byte
const bytes = window.atob(base64.split(',')[1]);
//处理异常,将ascii码小于0的转换为大于0
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
file = new Blob( [ab] , {type : 'image/jpeg'});
file.name = name;
success(file);
}
img.onerror = (e) => {
error(e);
}
};
reader.onerror = (e) => {
error(e);
};
}
}
};
</script>