项目描述: 金融产品,我做的这个模块是H5写的移动端,上线后会发布到他们的app下。
问题描述:有一个验证身份证的功能,需要上传身份证正反面图片。银行接口要求大小不得超过500Kb; 必须位jepg格式。可以拍照。
(现在的手机拍照图片基本都很大的,所以在拍照时,就会出问题)
第一种解决办法: 在拍完照上传时,将图片压缩后再上传。
:参考:添加链接描述
第二种解决办法: 因为我这个是镶嵌在他们app下使用,所以会出现 插件 兼容问题,用以上办法会出现本地没问题,线上不行…
所以我又找到了app原生的拍照方法。
具体代码:
async getPicture(params: PickerOptions, env) {
const imgPackageHeader = 'data:image/jpeg;base64,'
const imgDefaultBase64Code
='/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABQAAD/4QMpaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgV2luZG93cyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMzM5RDY2ODMyNzQxMUU1QTJENkEwOTg5MjdGQTczNiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozMzM5RDY2OTMyNzQxMUU1QTJENkEwOTg5MjdGQTczNiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjMzMzlENjY2MzI3NDExRTVBMkQ2QTA5ODkyN0ZBNzM2IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjMzMzlENjY3MzI3NDExRTVBMkQ2QTA5ODkyN0ZBNzM2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/+4ADkFkb2JlAGTAAAAAAf/bAIQAAgICAgICAgICAgMCAgIDBAMCAgMEBQQEBAQEBQYFBQUFBQUGBgcHCAcHBgkJCgoJCQwMDAwMDAwMDAwMDAwMDAEDAwMFBAUJBgYJDQsJCw0PDg4ODg8PDAwMDAwPDwwMDAwMDA8MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAEAAQAwERAAIRAQMRAf/EAG8AAAMBAAAAAAAAAAAAAAAAAAQFBggBAAIDAAAAAAAAAAAAAAAAAAMEBQcIEAABBAEDBAMAAAAAAAAAAAABAgMEBQYAERIhMUEHYSIUEQACAgAGAgMBAAAAAAAAAAABAhEDACFREgQFMUFhoRQi/9oADAMBAAIRAxEAPwDWfripp7WwyFy7q13MWmoZtmzXIecYLr0ct8U82vsN+RGq06+pHZt67gqkxMZiNMaH73k3U11ip9hexV3QDAafRywd7BxuorKfDchrKaXjLmTtTVS8cmPl9TP5HUIQ8hTiUOcHgokch46EjronP46IldiqV3T/ACTMQfOsH5wHpOfdddfRY62CsrDqIncCSDBIlYzjXPCbBMsGHy76ehyUxNn0kuvq5UTYLZlPFBbcKipJSElPUjc/Gg8LlfnZmzkqQI9E4a7jrf3pWhAKrYrMD4KiZHg64mLW4tr2WqfdWcq1mrASqVLdW85xHZIUskgDwOw0tbc9rbnJJ+c8SHG4tXGTZUgVdAAB9Y//2Q=='
if (env === 'local') {
//本地调试
return new Promise((resolve, reject) => {
resolve({
base64Code: imgDefaultBase64Code,
base64Url: imgPackageHeader + imgDefaultBase64Code,
})
})
}
//测试或者生产环境
const opt: PickerOptions = {
quality: params.quality || 75,
destinationType: params.destinationType || 0,
allowEdit: params.allowEdit || false,
encodingType: params.encodingType || 0,
targetWidth: params.targetWidth || 375,
targetHeight: params.targetHeight || 667,
saveToPhotoAlbum: params.saveToPhotoAlbum || false,
sourceType: params.sourceType || 0,
mediaType: params.mediaType || 0,
correctOrientation: params.correctOrientation || true,
cameraDirection: params.cameraDirection || 0,
}
return new Promise((resolve, reject) => {
try {
navigator.camera.getPicture<PickerOptions>(
(data) => {
resolve({
base64Code: data,
// base64Url: imgPackageHeader + data,
base64Url: data,
})
},
(data) => {
reject(data)
},
opt
)
} catch (e) {
console.log('_warn', 'Cordova maybe not exist.')
reject(e)
}
})
},
配置信息备注:
let opt ={
quality: params.quality || 80,// 相片质量0- 100。
destinationlype: params.destiationlype || 0, // 返回类型: DATA URL = 0,返作为 base64 字符串; FILE URI = 1,返回影像的 URI: NATIVE URI = 2,返回图像信息、
allowEdit: params.allowEdit || false, //在选择之前台许修改截愿
encodingType: paramsencodingType || 0 //保存的图片格式: JPEG = 0,PNG =1
targetwWidth: params.targetwidth || 1200,// 照片宽度
targetHeight: params.targetHeight || 1200,// 照片高度
saveToPhotoAlbum: params.saveToPhotoAlbum || false,// 保存进手机相册
sourceType: params,sourceType || 0, // 里选择图片: PHOTOLIBRARY(M设相册择图片) = 0; 相机拍 = 1; SAVEDPHOTOALBUM = 2 0和1其实都是本地图库
mediaType: params.mediatype || 0, // 可媒体类型: 片=0,认值,只许选择图片返回指定Destinatintype的参数;提频格=1,允许选择视频, 最终返回 FILEURI(网址);ALL
correctOrientation: params.correctOrientation || true,
cameraDirection: params,cameraDirection || 0 // 选择摄像头类型(前置提像头或者后面的摄像头): Back = 0(后置),Front-facing = 1(前置)
}
页面引入使用: import nativeApi from '@/utils/native-api' 上面方法我封装在native-api文件nativeApi中,使用时需要引入
HTML
上传控件:
<div class="video-box" @click="openCamera(1)">
<div v-if="!image0" class="photo-box1"></div>
<div v-else class="photo-box1-son">
<img :src="image0" />
</div>
</div>
选择拍照还是相册弹框
<van-popup v-model:show="popupShow" position="bottom">
<div class="popup-box">
<div class="popup-box-title">请选择照片来源</div>
<div class="popup-box-text" @click="handCamera(1)">拍照</div>
<div class="popup-box-text" @click="handCamera(0)">相册</div>
<div class="popup-box-text quxiao" @click="popupShow = false">取消</div>
</div>
</van-popup>
重要参数:
openCamera:点击拉取拍照事件
image0: 上传成功后的回显图片,
事件:
const openCamera = async (type) => {
// console.log(popupShow,6767676);
squareType.value = type // 这里做的是身份证上传,所以type是我用来判断上传正面还是背面的
popupShow.value = true // 这里我做了选择 拍照 还是 相册 的选择框。
}
选择上传方式:
const handCamera = (type) => {
sourceType.value = type
console.log(squareType.value, '1正2反')
console.log(sourceType.value, '0册1相机')
xuanzeCamera(squareType.value, sourceType.value) // squareType: 1正面,2反面; sourceType:1相机,0相册
}
选择上传方式后,调取接口:
const xuanzeCamera = async (type, sourceType) => { // 取值看上面、
const res = await nativeApi.getPicture({ // nativeApi.getPicture
quality: 80,
sourceType: sourceType, //只允许使用摄像头
encodingType: 0,
cameraDirection: 0, //后置
saveToPhotoAlbum: true, //保存进手机相册
targetHeight: 800,
targetWidth: 600,
})
console.log(res, 'dddddddddddd')
if (res.base64Url) {
if (type === 1) {
// 正面
uploadFiles.value = {} // uploadFiles.value调取接口时的传参
image0.value = 'data:image/jpeg;base64,' + res.base64Url // 页面回显
uploadFiles.value.content = res.base64Url + ''
popupShow.value = false // 关闭选择 拍照 / 相册 弹框
} else if (type === 2) {
// 反面
if (uploadFiles.value.content) {
image1.value = 'data:image/jpeg;base64,' + res.base64Url
uploadFiles.value.content1 = res.base64Url + ''
uploadFiles.value.contentType = 'image/jpeg'
popupShow.value = false
getImage(uploadFiles.value) // 调取封装的接口 、
} else {
uploadFiles.value = {}
Dialog({ message: '请先上传正面!' })
}
}
}
}
备注:该方法本地没法测试。我是在他们app测试的。完美运行!(建议使用第一种,第二种兼容问题)