You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Expo上传takePictureAsync图片至Digital Ocean Space后无法预览

问题描述

使用Expo的takePictureAsync拍摄图片后,通过签名PUT URL上传至Digital Ocean Spaces,文件上传成功且大小正常,但预览URL无法渲染图片。尝试移除data:image/png;base64前缀后仍未解决。

原代码:

const pictureResponse = await camera.current.takePictureAsync({ base64: true });

const spacesBase64 = `data:image/png;base64,${pictureResponse.base64}`;
const spacesBuffer = Buffer.from(spacesBase64, "base64");
const spacesBlob = new Blob([spacesBuffer]);
const spacesFile = new File([spacesBlob], "test.jpg", { type: "image/jpeg" });

fetch(`https://signedputurl.com`, { method: 'PUT', body: spacesFile });
问题原因及修复方案
  1. Base64解码错误:pictureResponse.base64本身就是纯图片的Base64编码,添加data:image/png;base64前缀后,Buffer会把前缀也当作Base64内容解码,直接导致图片数据损坏。
  2. Expo环境Buffer兼容性问题:React Native/Expo里的Buffer是polyfill实现,直接用它转Blob容易出问题,换成Uint8Array处理更可靠。
  3. 冗余的File转换:上传时不需要把Blob转成File,直接用Blob作为请求体即可,减少不必要的转换步骤。

修复后的代码:

const pictureResponse = await camera.current.takePictureAsync({ base64: true });

// 直接使用返回的纯base64数据,无需添加前缀
const base64Data = pictureResponse.base64;

// 将base64转为Uint8Array,再生成对应格式的Blob
const uint8Array = Uint8Array.from(atob(base64Data), char => char.charCodeAt(0));
const imageBlob = new Blob([uint8Array], { type: pictureResponse.type || 'image/jpeg' });

// 发起PUT请求上传Blob
await fetch('https://signedputurl.com', {
  method: 'PUT',
  body: imageBlob,
  headers: {
    // 若签名URL限制了Content-Type,需与Blob的type保持一致
    'Content-Type': pictureResponse.type || 'image/jpeg'
  }
});

额外注意:

  • 如果拍摄时指定了format: 'png',要同步修改Blob的type为image/png,文件名也对应调整为.png。
  • 确认签名PUT URL的配置是否允许对应的Content-Type,部分签名URL会限制上传的文件类型。

内容的提问来源于stack exchange,提问作者Schotsl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 04:20:54