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

使用Expo Image Picker转Blob后图片无法显示问题排查

问题:Expo Image Picker图片转Blob后无法跨端显示

我开发了一款简易聊天应用,用户可提交消息,还能通过Expo ImagePicker选图提交,这部分功能正常。但图片URI指向本地文件,我想将其转换为Blob以便存储到Node.js+PostgreSQL后端。目前尝试通过Blob URI显示图片却失败了,求排查代码问题。(未使用.blob()方法,因其兼容性不佳,需要适配iOS、Android和Web的跨端解决方案)

相关函数代码

function dataURItoBlob(dataURI) {
  // convert base64/URLEncoded data component to raw binary data held in a string
  var byteString;
  if (dataURI.split(",")[0].indexOf("base64") >= 0)
    byteString = atob(dataURI.split(",")[1]);
  else byteString = unescape(dataURI.split(",")[1]);

  // separate out the mime component
  var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];

  // write the bytes of the string to a typed array
  var ia = new Uint8Array(byteString.length);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }

  return new Blob([ia], { type: mimeString });
}

const pickImage = async () => {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.All,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
    base64: true,
  });

  if (!result.canceled) {
    let filename = result?.assets[0].uri.substring(
      result?.assets[0].uri.lastIndexOf("/") + 1,
      result?.assets[0].uri.length
    );

    setImage(result.assets[0].uri);
    console.log(image);

    delete result.cancelled;
    result = {
      ...result,
      name: filename,
    };
  }
};

提交时的处理逻辑

onSubmit={(values, actions) => {
  if (image !== null) {
    let imgblob = dataURItoBlob(image);
    let bloburl = URL.createObjectURL(imgblob);
    setBlobUrl(bloburl);
  } else {
    const imgblob = null;
    const bloburl = null;
  }
}}

图片渲染代码

<Text>blobUrl is {blobUrl}</Text>
{blobUrl && (
  <Image
    source={{ uri: blobUrl }}
    style={{ width: 300, height: 200, marginBottom: 5 }}
  />
)}

问题原因分析

核心错误是你传给dataURItoBlob的是本地文件URI(如file:///xxx),但该函数仅能处理标准的base64格式DataURI(如data:image/jpeg;base64,xxxxxx)。虽然你在ImagePicker配置中开启了base64: true,但并没有使用返回的base64数据,反而用了本地文件路径的uri字段,导致转换后的Blob完全无效。

修复方案

1. 修改pickImage函数,保存标准DataURI

将原本保存本地URI的逻辑改为保存包含base64的DataURI:

const pickImage = async () => {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.All,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
    base64: true,
  });

  if (!result.canceled) {
    const asset = result.assets[0];
    // 拼接成标准的DataURI格式
    const dataURI = `data:${asset.mimeType};base64,${asset.base64}`;
    setImage(dataURI);

    let filename = asset.uri.substring(
      asset.uri.lastIndexOf("/") + 1,
      asset.uri.length
    );

    delete result.cancelled;
    result = {
      ...result,
      name: filename,
    };
  }
};

2. 保留原有提交与渲染逻辑

修改后,image变量已经是标准DataURI,dataURItoBlob可以正确转换为Blob,生成的Blob URL也能被React Native(包括Web端)的Image组件正常识别渲染。

3. 跨端兼容性说明

  • 该方案适配iOS、Android和Web所有平台,因为DataURI和Blob的处理逻辑都是通用的浏览器/JS环境API。
  • 若担心大图片的base64内存占用,可调整ImagePicker的quality参数(如设为0.8)降低图片体积。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:55:13