前言:我做的项目是H5嵌套小程序。要实现的功能是拍照功能,且,在未调用接口前有预览功能。
拍照功能:
补充:手机端是拍照直接调用设备摄像头拍照,web端是上传图片的形式。
因为input type="file"
默认的‘请选择上传文件’以及上传后显示的文件名不支持修改和配置。所以我采用曲线实现修改显示文件以及不显示文件名的方式:上层标签覆盖的形式,具体看代码:
html:
<label for="camera">
<div class="camera">
<div class="txt">点击拍照</div>
<input
id="camera"
ref="camera"
type="file"
accept="image/*"
capture="camera"
@change="handleInputChange"
>
</div>
</label>
之所以加label,是为了能在点击上层自定义样式的时候,触发input type="file"
标签的事件。
css:
<style lang="less" scoped>
.camera {
width: 65px;
height: 40px;
overflow: hidden;
font-size: 16px;
position: relative;
.txt {
position: absolute;
width: 100%;
height: 100%;
background-color: #e8e8e8;
}
}
</style>
实现图片预览:
涉及到拿到上传的图片的文件(file),然后讲file
转成base64
形式,用img显示出来。重点就在于文件转base64。
html:
<img
v-if="imgSrc"
:src="'data:image/png;base64,' + imgSrc"
alt="图片"
style="width: 200px"
>
需要注意的是,转的结果是base64,在用img
显示的时候,src
需要拼接上头部'data:image/png;base64,'
一定要拼,不然图片显示不出来。
js:
handleInputChange() {
this.getCamera();
},
async getCamera() {
const fileName = this.$refs.camera.value;
const file = this.$refs.camera.files[0];
console.log("fileName:", fileName);
console.log("file:", file);
// let blob = new Blob(file); // 返回的文件流数据
// let url = window.URL.createObjectURL(blob); // 将他转化为路径
this.imgSrc = await this.fileToBase64(file);
},
fileToBase64(file) {
return new Promise((resolve, reject) => {
// 创建一个新的 FileReader 对象
const reader = new FileReader();
// 读取 File 对象
reader.readAsDataURL(file);
// 加载完成后
reader.onload = function () {
// 将读取的数据转换为 base64 编码的字符串
const base64String = reader.result.split(",")[1];
// 解析为 Promise 对象,并返回 base64 编码的字符串
resolve(base64String);
};
// 加载失败时
reader.onerror = function () {
reject(new Error("Failed to load file"));
};
});
},
如有不妥,欢迎指正,谢谢~~