如何使用cordova-plugin-media-capture显示Android端捕获的图片?
解决cordova-plugin-media-capture捕获图片后无法显示的问题
嘿,我来帮你搞定这个问题!你遇到的TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'错误,核心原因其实有两个:
captureImage的成功回调返回的不是单个文件对象,而是MediaFile对象数组——哪怕你只捕获一张图片,它也是包在数组里的;- Cordova的MediaFile对象并不是浏览器标准的Blob/File类型,直接传给
FileReader.readAsDataURL肯定会报错。
修正后的完整代码
我给你调整了代码,同时处理了数组问题和MediaFile转Blob的逻辑,你可以直接用:
function capturePhoto() { navigator.device.capture.captureImage( // 成功回调:注意这里接收的是MediaFile数组 mediaFiles => { // 取第一张捕获的图片(如果只需要一张的话) const mediaFile = mediaFiles[0]; convertMediaFileToBase64(mediaFile) .then(b64 => { document.getElementById('fsPhotoI').src = b64; }) .catch(e => alert(`转换失败:${e.message}`)); }, error => { alert(`捕获失败:${error.message}`); }, { limit: 1 } // 限制只捕获一张,按需调整数量 ); } // 把MediaFile转成Base64的工具函数 function convertMediaFileToBase64(mediaFile) { return new Promise((resolve, reject) => { // 用Cordova的File API解析本地文件路径 window.resolveLocalFileSystemURL(mediaFile.fullPath, fileEntry => { fileEntry.file(file => { const reader = new FileReader(); reader.onloadend = () => { resolve(reader.result); // 这里就是base64格式的图片数据啦 }; reader.onerror = () => { reject(reader.error); }; reader.readAsDataURL(file); // 现在file是标准Blob类型,能正常读取了 }, reject); }, reject); }); }
关键细节要注意
- 别忽略数组结构:一定要记得
captureImage返回的是数组,哪怕设置了limit:1,也要通过索引取元素; - 依赖Cordova File API:必须通过
resolveLocalFileSystemURL把MediaFile的fullPath解析成FileEntry,再通过fileEntry.file()拿到标准的File对象(它是Blob的子类),这样FileReader才能正常工作; - 权限不能忘:确保你的AndroidManifest.xml已经加了必要的权限:
如果是Android 10及以上版本,还需要在application标签里加<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />android:requestLegacyExternalStorage="true"(旧版Cordova可能需要这个)。
更简单的替代方案(不用转base64)
其实你也可以跳过转base64的步骤,直接用Cordova的文件路径显示图片,效率更高:
function capturePhoto() { navigator.device.capture.captureImage( mediaFiles => { const mediaFile = mediaFiles[0]; // Android上要确保路径带file://前缀(有些插件版本会自动加,有些不会) const imageUrl = mediaFile.fullPath.startsWith('file://') ? mediaFile.fullPath : `file://${mediaFile.fullPath}`; document.getElementById('fsPhotoI').src = imageUrl; }, error => alert(error.message), { limit:1 } ); }
这个方法适合直接显示图片的场景,省掉了转码的过程,速度更快。
内容的提问来源于stack exchange,提问作者Chong Lip Phang
相关产品推荐
相关产品推荐

