【问题标题】:expo-image-manipulator won't take uri from expo-image-pickerexpo-image-manipulator 不会从 expo-image-picker 中获取 uri
【发布时间】:2021-04-02 18:42:31
【问题描述】:

我正在使用 expo-image-picker 来获取本地存储图像的图像 uri。我想在将图像发送到后端之前使用 expo-image-manipulator 调整图像大小,但是 expo imageManipulator 不会从 expo 图像选择器中获取 uri。这些错误是在安卓模拟器上的 expo 中运行时发生的。

这是获取 uri 的基本代码:

import * as ImagePicker from "expo-image-picker";

const selectImage = async () => {
try {
  const result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    quality: 0.5,
  });
  if (!result.cancelled) onChangeImage(result.uri);
} catch (error) {
  console.log("Error reading an image", error);
}

};

我可以将此图像直接发送到后端并将其保存到我的 S3 中。当我 console.log(uri) 时,我得到的是:

文件:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FThredFit-59f4d533-f203-4efb-bcb0-6a5786d44584/ImagePicker/0ea74111-8677-4074-81af-5fbc1f0758d5.jpg

现在我尝试将其输入到下面的图像调整器中(作为 imageUri):

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

const setSize = async (imageUri, width, height) => {
try {
  const manipResult = await ImageManipulator.manipulateAsync(
    imageUri,
    [{ resize: { width: width, height: height } }],
    { format: 'jpeg' }
);
  console.log(manipResult);
} catch (error) {
  console.log("Error manipulating image: ", error);
}

};

我在 android 模拟器上收到以下错误:

abi38_0_0.com.facebook.react.bridge.ReadableNativeMap 无法转换为 java.lang.String

如果我首先对 imageUrl 进行字符串化,那么我会克服这个错误,但调整大小会抛出一个错误,说它无法解码图像:

[错误:无法获得“文件:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FThredFit-59f4d533-f203-4efb-bcb0-6a5786d44584/ImagePicker/0ea74111 的解码位图-8677-4074-81af-5fbc1f0758d5.jpg": java.lang.Exception: 加载位图失败]

Image of the emulator error image of the logged error

【问题讨论】:

  • file:/data/user/0/host.exp..... 那应该是file:///data/user/0/host.exp..... 无论如何从该字符串中删除file:/。并意识到通常你应该删除file://,因为那是协议。然后你会得到/data/user/0/host.exp.... 作为路径。
  • 谢谢@blackapps!!!我刚刚尝试手动输入路径字符串的不同变体,而 file:///data/user/0/host.exp....... 最终起作用了。这是记录的结果:manipResults: Object { "height": 39, "uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FThredFit-59f4d533-f203-4efb-bcb0-6a5786d44584/ImageManipulator/36e913d6-98b1-4899-a3d7-d3e5d3675641.jpg", "width": 50, }
  • 我想知道 expo-image-picker uri 是否总是如此,我只需要在发送到 expo-image-manipulator 之前对 uri 进行字符串化并添加 '//' 或者如果这是特定于android或模拟器的......

标签: android react-native expo image-manipulation imagepicker


【解决方案1】:

很难确切地看到这里发生了什么,因为您没有提供所有相关代码。我怀疑您遇到的问题是对对象进行字符串化,而不是从中获取适当的值。以下是 ImagePicker 和 ImageManipulator 集成的示例:https://snack.expo.io/@brents/image-picker-and-manipulator

import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as ImageManipulator from 'expo-image-manipulator';
import Constants from 'expo-constants';

export default function ImagePickerExample() {
  const [image, setImage] = useState(null);

  useEffect(() => {
    (async () => {
      if (Platform.OS !== 'web') {
        const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
        if (status !== 'granted') {
          alert('Sorry, we need camera roll permissions to make this work!');
        }
      }
    })();
  }, []);

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

    console.log(result);

    if (result.cancelled) {
      return;
    }

    const manipResult = await ImageManipulator.manipulateAsync(
      result.localUri || result.uri,
      [{ rotate: 90 }, { flip: ImageManipulator.FlipType.Vertical }],
      { compress: 1, format: ImageManipulator.SaveFormat.PNG }
    );

    setImage(manipResult.uri);
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="Pick an image from camera roll" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
    </View>
  );
}

【讨论】:

  • 谢谢@brentvatne。这基本上就是我一开始在做的事情。我像您一样将 result.uri 直接传递给 ImageManipulator.manipulateAsync() ,但图像操纵器位于单独的组件中。我将在具有图像选择器的组件中尝试您的代码,看看这是否有效。将在我女儿的生日晚餐后回来报告:)
  • @brentvtne,谢谢!!!这行得通!我将图像操纵器保存在单独的组件中。唯一的区别是,在我将 result.uri 设置为状态变量并将其传递给 imageManipulator.manipulateAsync(uri,.. 之前,现在我正在传递整个结果并使用您的:ImageManipulator.manipulateAsync(result.localUri || result.uri, ...
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 2020-11-04
  • 2020-03-02
  • 2022-12-10
  • 2022-12-13
  • 1970-01-01
  • 2022-10-22
  • 1970-01-01
相关资源
最近更新 更多