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

React Expo中如何利用Image Picker获取的Uri实现图片上传至服务器?

在React Expo中实现类似Android Bitmap的图片上传功能

Hey there! I’ve gone through similar Android-to-Expo image upload workflows before, so let’s map your original Android Bitmap logic directly to Expo’s tooling to get the same result.

Your original Android flow was:

获取Bitmap → 缩放至500x500 → 压缩为JPEG(100%质量)→ 转Base64 → 上传至服务器

Here’s how to replicate this step-by-step in React Expo:

1. 安装必要依赖

First, install the Expo libraries we’ll need for image picking and manipulation:

npx expo install expo-image-picker expo-image-manipulator

2. 完整实现代码

Let’s break this into reusable functions that mirror your Android logic:

步骤1:获取图片Uri(你已经完成这部分,但这里是完整流程)

import * as ImagePicker from 'expo-image-picker';
import * as ImageManipulator from 'expo-image-manipulator';

const pickImage = async () => {
  // 请求相册权限
  const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
  if (!permissionResult.granted) {
    alert("需要相册权限才能选择图片哦");
    return;
  }

  // 从相册选择图片
  const pickerResult = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    allowsEditing: false,
    quality: 1, // 先获取原图,后续我们自己处理压缩
  });

  if (!pickerResult.canceled) {
    // 拿到图片Uri后,开始处理并上传
    await processAndUploadImage(pickerResult.assets[0].uri);
  }
};

步骤2:缩放图片 + 生成Base64

This part directly replaces your Bitmap scaling and compression code:

const processAndUploadImage = async (imageUri) => {
  try {
    // 缩放图片到500x500,和你Android里的逻辑完全一致
    const manipulatedImage = await ImageManipulator.manipulateAsync(
      imageUri,
      [{ resize: { width: 500, height: 500 } }], // 固定宽高缩放
      {
        format: ImageManipulator.SaveFormat.JPEG,
        quality: 1, // 对应Android的100%压缩质量
        base64: true, // 直接输出Base64字符串
      }
    );

    // 拿到编码后的图片字符串
    const encodedImage = manipulatedImage.base64;

    // 上传到服务器
    await uploadToServer(encodedImage);
  } catch (error) {
    console.error("图片处理失败:", error);
    alert("图片处理出错,请重试");
  }
};

步骤3:上传Base64到服务器

This sends the Base64 string to your server, just like your Android code did:

const uploadToServer = async (encodedImage) => {
  try {
    const response = await fetch("你的服务器上传接口地址", {
      method: "POST",
      headers: {
        "Content-Type": "application/json", // 按服务器要求调整Content-Type
      },
      body: JSON.stringify({
        image: encodedImage, // 字段名要和你Android端传给服务器的一致
      }),
    });

    if (!response.ok) {
      throw new Error(`服务器响应异常: ${response.status}`);
    }

    const result = await response.json();
    console.log("上传成功!", result);
    alert("图片上传完成");
  } catch (error) {
    console.error("上传失败:", error);
    alert("图片上传出错,请重试");
  }
};

可选:用FormData上传(更高效)

If your server supports multipart/form-data uploads, this is a better option than Base64 (since Base64 adds ~30% extra file size). Here’s how to adjust the upload step:

import { Platform } from 'react-native';

const uploadWithFormData = async (imageUri) => {
  // 先缩放图片(和之前一样)
  const manipulatedImage = await ImageManipulator.manipulateAsync(
    imageUri,
    [{ resize: { width: 500, height: 500 } }],
    { format: ImageManipulator.SaveFormat.JPEG, quality: 1 }
  );

  // 构造FormData
  const formData = new FormData();
  // 适配Android/iOS的Uri格式
  const adjustedUri = Platform.OS === "android" 
    ? manipulatedImage.uri 
    : manipulatedImage.uri.replace("file://", "");
  
  formData.append("image", {
    uri: adjustedUri,
    type: "image/jpeg",
    name: "uploaded_image.jpg",
  });

  try {
    const response = await fetch("你的服务器上传接口地址", {
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data",
      },
      body: formData,
    });

    // 后续处理和之前一致
    if (!response.ok) throw new Error(`服务器响应异常: ${response.status}`);
    const result = await response.json();
    console.log("上传成功!", result);
    alert("图片上传完成");
  } catch (error) {
    console.error("上传失败:", error);
    alert("图片上传出错,请重试");
  }
};

关键对应点

  • Bitmap.createScaledBitmap() → ImageManipulator.manipulateAsync() with resize option
  • bitmap.compress(JPEG, 100, baos) → ImageManipulator with format: JPEG and quality: 1
  • Base64.encodeToString() → ImageManipulator with base64: true

内容的提问来源于stack exchange,提问作者E.Shahri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:32:35