可以在手机上微信、支付宝、钉钉、浏览器中使用
用原生的input调起手机摄像头
<input type="file" class="upImage" accept="image/*" @change="onFileChange" />
input的 capture=“camera” 这个属性 可以调起手机摄像头
但安卓和IOS 加上capture在不同场景下(微信、支付宝、钉钉)有的能同时调起相机和相册 有的只能调起相机
两者不加上capture则都可以调用相机和相册 目前没遇到调不起相册的情况
方法:
onFileChange(e) {
let file = e.target.files[0];
//对文件检查
let allType = "image/png,image/gif,image/jpeg,image/jpg,image/svg";
if (allType.indexOf(file.type) == "-1") {
this.$vux.toast.text("请选择图片文件");
return false;
}
this.$vux.loading.show()
let param = new FormData(); //创建form对象
param.append("file", file); //通过append向form对象添加数据
//这里的param已经是一个文件流了 但是我想压缩下图片再上传 如果不需要压缩 可以直接接口上传
this.imgPreview(file);
},
// canvas压缩图片
compress(img) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
let initSize = img.src.length;
let width = img.width;
let height = img.height;
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, width, height);
console.log(initSize);
//进行最小压缩
let ndata = canvas.toDataURL("image/jpeg", 0.2); //这个0.2是可变的 数值越小 压缩的越厉害 很小图会失真 0.2还是可以接受的
console.log("*******压缩后的图片大小*******", ndata.length);
return ndata;
},
//压缩后的图片再转换成文件
dataURLtoFile(dataurl, filename = "file") {
let arr = dataurl.split(",");
let mime = arr[0].match(/:(.*?);/)[1];
let suffix = mime.split("/")[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], `${filename}.${suffix}`, { type: mime });
},
//上传文件
imgPreview(file) {
let that = this;
// 判断是否支持FileReader
if (!file || !window.FileReader) return;
// 创建一个reader
var reader = new FileReader();
// 将图片转成base64格式
reader.readAsDataURL(file);
// 读取成功后的回调
reader.onloadend = function() {
let result = this.result;
let img = new Image();
img.src = result;
// console.log("============未压缩图片===========");
// console.log(result.length);
img.onload = function() {
let data = that.compress(img);//压缩
// console.log(data.length);
that.imgUrl = result;
var formData = new FormData();
let a = that.dataURLtoFile(data);//压缩后转换成文件
let param = new FormData(); //创建form对象
param.append("file", a); //通过append向form对象添加数据
// return;
let config = {
headers: { "Content-Type": "multipart/form-data" }
};
//$http是封装的Axios
that.$http
.post("common/oss/upload", param, config)
.then(res => {
if (res.data.code = 200){
that.localIdImgs.push(res.data.data.url);//上传成功会返回图片链接
}
that.$vux.loading.hide();
})
.catch(err => {
that.$vux.loading.hide();
});
};
};
},
后端接口只接收文件
因此 流程是 获取文件 >>转换成base64>>canvas压缩>>转化成文件>>接口上传
做出来的效果:
预览图片
之前用的是vux的Previewer
官网上有一句描述:“注意避免使用过大图片,否则可能会出现卡顿黑屏的情况(尤其是在 Android 机子上) #2514。“
手机拍摄的图片 基本上都是几M的 iPhone手机拍出来的还有10M多的 压缩完也不小 亲测 卡 :(
于是用了最最简单的 点击放大预览
html:
<ul class="list-ul">
<li class="list-li" v-for="(iu, index) in localIdImgs" :key="index">
<!--显示的图片-->
<a class="list-link" @click="show(index)">
<img class="previewer-demo-img" :src="iu" />
</a>
<!--删除图标-->
<span class="iconfont icon-shanchu" @click="delImage(index)"> </span>
</li>
<!--添加图片-->
<li class="list-li-add" v-if="localIdImgs.length<5">
<div class="list-default-img">
<span class="iconfont icon-xiangji"></span>
<span class>{{localIdImgs.length}}/5</span>
<input type="file" class="upImage" accept="image/*" @change="onFileChange" />
</div>
</li>
</ul>
<!--显示预览的图片-->
<div v-if="imgShow" class="previewer" @click.stop="imgShow=false">
<img class="previewer-demo-img" :src="previewerImg" />
</div>
js:
data() {
return {
localIdImgs:[],//存图片链接
imgShow:false,//显示预览
previewerImg:'',//当前预览的图片
}
},
methods: {
//删掉图片
delImage(index) {
this.localIdImgs.splice(index, 1);
},
//预览图片
show(index) {
this.previewerImg = this.localIdImgs[index];
this.imgShow = true;
},
}
css:
.list-ul {
padding: 0.32rem 0.24rem;
padding-top: 0.1rem;
height: 1.6rem;
width: 6.9rem;
.list-li {
position: relative;
}
.list-li-add {
width: 1.2rem;
height: 1.2rem;
border: 0.02rem dashed rgba(230, 230, 230, 1);
position: absolute;
}
li {
width: 1.2rem;
height: 1.2rem;
margin-right: 0.1rem;
display: inline-block;
}
li:last-child {
margin-right: 0;
}
.list-default-img {
color: #ccc;
text-align: center;
padding-top: 0.1rem;
position: relative;
.iconfont {
font-size: 0.48rem;
display: block;
height: 0.55rem;
}
span:nth-child(2) {
font-size: 0.23rem;
}
.upImage {
position: absolute;
top: 0;
left: 0;
width: 1.2rem;
height: 1.2rem;
opacity: 0;
}
}
.icon-shanchu {
height: 0.32rem;
position: absolute;
top: -0.22rem;
right: -0.12rem;
background: #fff;
z-index: 1000;
border-radius: 100%;
}
}
.previewer {
z-index:1000;
width: 100%;
height: 100%;
position: fixed;
top: 0;
background: #000;
img {
width: 100%;
height: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
}
从网上找了很多方法 完成这个功能 记录一下( ̄▽ ̄")