dlwiest
dlwiest

Reputation: 655

Sending base64 image uri to ImageManipulator

I'm trying to display thumbnails for a list of items in a mobile app. The API returns a full sized image, which I'm retrieving via XMLHttpRequest and then using FileReader to convert to base64.

http.onreadystatechange = () => {
    if (http.readyState !== 4) return;
    if (http.status === 200 && http.response) {
        const fileReader = new FileReader();
        fileReader.readAsDataURL(http.response);
        fileReader.onload = () => {
            const result = fileReader.result;
            resolve(result);
        };
    } else {
        resolve(false);
    }
};

http.send(JSON.stringify(params));

If I use the output of this as an or source, it works fine. However, I'd like to shrink the image first, since there's no reason to store the full size image in memory just to display a thumbnail, so after retrieving the full image from my API file, I'm trying to pass it to ImageManipulator.

const photo = await inventoryAPI.getPhoto(credentials, this.key);
const shrunk = await ImageManipulator.manipulateAsync(photo, [{ resize: { width: 320 } }], { base64: true });

For some reason though, ImageManipulator is throwing an error on this step: File 'data:image/jpeg;base64,[long image data string here]=' isn't readable

I'm sure there are others ways to compress base64 image data, but I'd like to know what the problem is here in case I need to perform any other operations on images retrieved this way. Any help would be appreciated. Thanks!

Upvotes: 0

Views: 2434

Answers (1)

hong developer
hong developer

Reputation: 13926

You can encoding base64 using filesystem in expo.

example.js

import { FileSystem } from 'expo'
...
const signature = await FileSystem.readAsStringAsync(item.signature, { encoding: FileSystem.EncodingTypes.Base64 })

OR

You can encoding base64 using ImagePicker in expo.

example.js

import React, { Component } from 'react';
import { Button, Image, Text, View, StyleSheet } from 'react-native';
import { ImagePicker, Constants } from 'expo';

export default class App extends Component {
  state = {
    pickerResult: null,
  };

  _pickImg = async () => {
    let pickerResult = await ImagePicker.launchImageLibraryAsync({
      base64: true,
      allowsEditing: false,
      aspect: [4, 3],
    });

    this.setState({
      pickerResult,
    });
  };

  render() {
    let { pickerResult } = this.state;
    let imageUri = pickerResult ? `data:image/jpg;base64,${pickerResult.base64}` : null;
    imageUri && console.log({uri: imageUri.slice(0, 100)});

    return (
      <View style={styles.container}>
        <Button onPress={this._pickImg} title="Open Picker" />
        {pickerResult
          ? <Image
              source={{uri: imageUri}}
              style={{ width: 200, height: 200 }}
            />
          : null}
        {pickerResult
          ? <Text style={styles.paragraph}>
              Keys on pickerResult:
              {' '}
              {JSON.stringify(Object.keys(pickerResult))}
            </Text>
          : null}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
    color: '#34495e',
  },
});

it is link about Image Picker

Upvotes: 1

Related Questions