如何通过Ionic 6 Capacitor Camera插件上传图片至Cloudinary
Ionic 6 + Capacitor 上传图片至Cloudinary实现方案
问题背景
开发含表单的Ionic 6应用,表单包含两个字符串输入框和一张图片。通过Capacitor Camera插件获取图片后,返回数据非File类型,需直接上传至Cloudinary,无需在用户设备存储图片。Capacitor Camera支持三种返回类型:
CameraResultType: uri = 'uri' base64 = 'base64' DataUrl = 'dataUrl'
当前相册选择图片代码:
// 相册选择逻辑 async getPicture() { const image = await Camera.getPhoto({ quality: 90, source: CameraSource.Photos, promptLabelHeader: '上传图片', promptLabelPhoto: '相册', promptLabelCancel: '取消', correctOrientation: true, resultType: CameraResultType.Uri }); console.log('image:', image); } // 相册选择逻辑结束
实现方案
一、基于Uri类型的上传(当前代码使用的类型)
通过Uri转换为Blob,再包装成FormData上传至Cloudinary:
- Uri转Blob工具函数
async uriToBlob(uri: string): Promise<Blob> { const response = await fetch(uri); return response.blob(); }
- Cloudinary上传函数
替换代码中的你的云名称和你的上传预设名称(需在Cloudinary控制台创建未签名上传预设):
async uploadToCloudinary(blob: Blob, fileName: string) { const formData = new FormData(); formData.append('file', blob, fileName); formData.append('upload_preset', '你的上传预设名称'); try { const response = await fetch('https://api.cloudinary.com/v1_1/你的云名称/image/upload', { method: 'POST', body: formData }); const data = await response.json(); console.log('上传成功:', data.secure_url); return data.secure_url; // 返回云端图片地址,可用于表单提交 } catch (error) { console.error('上传失败:', error); throw error; } }
- 整合选择与上传逻辑
修改getPicture函数,完成从选图到上传的流程:
async getPicture() { const image = await Camera.getPhoto({ quality: 90, source: CameraSource.Photos, promptLabelHeader: '上传图片', promptLabelPhoto: '相册', promptLabelCancel: '取消', correctOrientation: true, resultType: CameraResultType.Uri }); // 转换Uri为Blob const blob = await this.uriToBlob(image.webPath || image.uri); // 上传至Cloudinary,自定义文件名(示例用时间戳避免重复) const imageUrl = await this.uploadToCloudinary(blob, `upload_${Date.now()}.jpg`); // 此处可将imageUrl与表单的两个字符串字段一起提交 console.log('图片云端地址:', imageUrl); }
二、基于Base64类型的上传
若将resultType改为CameraResultType.Base64,可直接用base64字符串上传:
- 修改选图逻辑
async getPicture() { const image = await Camera.getPhoto({ // 保留其他配置 resultType: CameraResultType.Base64 }); // 构造Cloudinary要求的base64格式字符串 const base64Data = `data:image/jpeg;base64,${image.base64String}`; const imageUrl = await this.uploadBase64ToCloudinary(base64Data); console.log('图片云端地址:', imageUrl); }
- Base64上传函数
async uploadBase64ToCloudinary(base64Data: string) { const formData = new FormData(); formData.append('file', base64Data); formData.append('upload_preset', '你的上传预设名称'); try { const response = await fetch('https://api.cloudinary.com/v1_1/你的云名称/image/upload', { method: 'POST', body: formData }); const data = await response.json(); return data.secure_url; } catch (error) { console.error('上传失败:', error); throw error; } }
三、基于DataUrl类型的上传
DataUrl本身已包含data:image/jpeg;base64,前缀,可直接复用Base64上传函数:
- 修改选图逻辑
async getPicture() { const image = await Camera.getPhoto({ // 保留其他配置 resultType: CameraResultType.DataUrl }); // 直接调用Base64上传函数 const imageUrl = await this.uploadBase64ToCloudinary(image.dataUrl); console.log('图片云端地址:', imageUrl); }
注意事项
- 确保Cloudinary上传预设设置为允许未签名上传(控制台→设置→上传→上传预设)
- 可根据需求调整图片质量参数,平衡清晰度与上传速度
- 如需添加文件夹、标签等自定义参数,可在FormData中追加对应字段(如
formData.append('folder', 'my-app-images'))
内容的提问来源于stack exchange,提问作者Ariel valverde
相关产品推荐
相关产品推荐

