Convert Image to base64 in react native - react-native

I have used react-native-image-picker and now I select image from the Photo library. To send the that image to API I have to convert it first into base64 and then into byte array. I have the filepath in response.uri. How do I do it?
When I did console.log(response) I am getting this in result
'Response = ', {
fileSize: 6581432,
longitude: -17.548928333333333,
uri: 'file:///Users/shubhamb/Library/Developer/CoreSimulator/Devices/B58314DF-F0A9-48D2-B68A-984A02271B72/data/Containers/Data/Application/63143214-8A03-4AC8-A79C-42EC9B82E841/tmp/2AACBC57-0C07-4C98-985E-154668E6A384.jpg',
fileName: 'IMG_0003.JPG',
latitude: 65.682895,
origURL: 'assets-library://asset/asset.JPG?id=9F983DBA-EC35-42B8-8773-B597CF782EDD&ext=JPG',
type: 'image/jpeg',
height: 2002,
width: 3000,
timestamp: '2012-08-08T18:52:11Z',
isVertical: false,
}

Since you're using react-native-image-picker, it already returns the Base64 value in its response
ImagePicker.showImagePicker(options, (response) => {
const base64Value = response.data;
});
Documentation for the response

I suddenly ran into this issue while updating my app. What I found is that previous react-native-image-picker used to provide base64 as response.data. But now there is an includeBase64 in the options object so that you can control whether you need the base64 data or not. So my code became something like the following
captureTradeLicenseImage() {
let options = {
maxHeight: 250,
maxWidth: 350,
includeBase64: true //add this in the option to include base64 value in the response
}
ImagePicker.launchCamera(options, (response) => {
console.log('Response = ', response)
if (response.didCancel) {
console.log('User cancelled image picker')
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error)
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton)
}
else if (response.fileSize > 5242880) {
Alert.alert(
"Nilamhut Say\'s",
"Oops! the photos are too big. Max photo size is 4MB per photo. Please reduce the resolution or file size and retry",
[
{ text: "OK", onPress: () => console.log('ok Pressed') }
],
{ cancelable: false }
)
}
else {
this.setState({tradeLicenseImageData: response.base64}) //access like this
}
})
}

The standalone expo FileSystem package makes this simple:
const base64 = await FileSystem.readAsStringAsync(photo.uri, { encoding: 'base64' });
https://docs.expo.io/versions/latest/sdk/filesystem/
https://github.com/expo/expo/tree/master/packages/expo-file-system
As 2019-09-27 this package handles both file:// and content:// uri's

I'm too late but if I can help others that is looking how to get the base64 data from an image:
In the options object you have to set the base64 option to true, like this:
const options = {
title: 'Choose an Image',
base64: true
};
ImagePicker.launchImageLibrary(options, response => {
console.log(response.data);
});

As simple as that:
import { CameraOptions, ImagePickerResponse, launchCamera } from 'react-native-image-picker';
Wrap in your component:
const [b64, setB64] = useState<string>("");
const manageImage = async (response: ImagePickerResponse) => {
if (response.didCancel) {
return;
} else if (response.assets) {
if (response.assets?.length > 0) {
setB64(response.assets[0].base64 ? response.assets[0].base64 : "");
}
}
}
launchCamera(options, (response) => {
manageImage(response);
});

Related

Getstream.io with React Native

I suffer from uploading image to getstream service. And it doesn't upload image.
Here is my code. I get the following error.
Here is my code.
const filter = { type: 'messaging', members: { $in: [userInfo.id] } };
const sort = [{ last_message_at: -1 }];
let channels;
await chatClient.queryChannels(filter, sort, {
watch: false,
state: true,
}).then((response) => {
channels = response;
})
const file = this.state.avatar;
let avatarURI;
channels[0].sendImage(file).then((response) => {
avatarURI = response.file;
console.log(avatarURI);
})

How to save pdf from an api response to file system in react native?

I'm receieving a blob from api and i want to save it as a pdf document to file system.But on saving I'm getting a file with size 0B in my mobile
Code
export const getParkingReciept = (bookindId) => {
return async function (dispatch, getState) {
try {
const TOKEN = getState().Auth.token;
const formdata = new FormData();
formdata.append("booking_id", bookindId);
RNFetchBlob.fetch(
'POST',
`${BASE_URL}parking-space/booking/receipt`,
{
'Accept': 'application/json',
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'multipart/form-data'
},[
{ name : 'booking_id', data: bookindId.toString()}
]
)
.then(
response => {
console.log("response is ",response);
response.blob().then(res=>console.log(checkPermission(res,response.taskId)));
console.log("pdf base64 is ", response.base64());
}
).catch((error) => {
// error handling
console.log("Error", error)
}
);
}catch (e) {
if (e.response) {
console.log("error response is ", e.response);
} else if (e.request) {
console.log(e.request);
} else {
console.log('Error', e);
}
console.log(e.config);
}
}
const checkPermission=async (file,name) => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: "Cool Photo App Camera Permission",
message:
"Cool Photo App needs access to your camera " +
"so you can take awesome pictures.",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK"
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can write to external storage");
var path = RNFS.DownloadDirectoryPath + '/'+name+".pdf";
console.log("pdf being written is ",file);
RNFS.writeFile(path, file, 'utf8')
.then((success) => {
console.log('FILE WRITTEN!');
RNFetchBlob.fs.scanFile([ { path : path, mime : "application/pdf" } ])
// .then(() => {
// console.log("scan file success")
// })
// .catch((err) => {
// console.log("scan file error")
// })
})
.catch((err) => {
console.log(err.message);
});
} else {
console.log("permission denied");
}
} catch (err) {
console.warn(err);
}
};
reponse I get from fetch is
on calling blob() function of response what I get is
There is type Application/pdf there ,but in base 64 string does not start with JVBERi it starts with some SFRUU,Is that a valid pdf file?. What am I missing ? what am I doing wrong here?
This answer solves your problem , gives you detailed explanation about how to download files from a network request using rn fetch blob
https://stackoverflow.com/a/56890611/7324484
Once you downloaded the file or you can open the pdf directly using
https://www.npmjs.com/package/react-native-pdf

Converting Base64 string into blob in React Native

i have been looking for a solution to convert Image from base64 string into Blob
i get my images via react-native-image-crop-picker
the image object i get is formatted in this way :
{
creationDate: "1299975445"
cropRect: null
data: "/9j...AA"
duration: null
exif: null
filename: "IMG_0001.JPG"
height: 2848
localIdentifier: "10...001"
mime: "image/jpeg"
modificationDate: "1441224147"
path: "/Users/...351F66445.jpg"
size: 1896240
sourceURL: "file:///Users/...IMG_0001.JPG"
width: 4288
}
which means i have the path and source url and image data as base64 string.
what i need is to upload the images that the user picks as blob file to the server.
so is there any way to do the conversion in react native.
ps: i have tried solutions i found online but non of them seems to work so far but none of them seems to work for me.
urlToBlob = (url) => new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onerror = reject;
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
resolve(xhr.response);
}
};
xhr.open('GET', url);
xhr.responseType = 'blob'; // convert type
xhr.send();
})
this.urlToBlob(data)
.then((blob) => {
console.log(blob);
});
i tried this peace of code and this what i got in my console :
{
_data:
blobId: "B69744A5-B8D7-4E6B-8D15-1C95069737EA"
name: "Unknown"
offset: 0
size: 1896240
type: "image/jpeg"
__collector: null
}
after a lot of search i found a solution if anyone faced this issue.
i used a package 'extract-files' it allowed me to the images as files in order to send them to the server
it worked like this:
import { ReactNativeFile } from 'extract-files';
const FormData = require('form-data');
_addImage = async () => {
const { images } = this.state;
if (images.imageData.length > 0) {
const formData = new FormData();
// converting images to files
images.imageData.forEach((element) => {
const file = new ReactNativeFile({
uri: element.sourceURL,
name: element.filename,
type: element.mime,
});
formData.append('files', file);
});
// sending files to the server
await addImages(formData).then((response) => {
console.log('response : ', response);
if (response.success) {
this.pictures = response.filesNames;
this.setState({
isLoading: true,
pictures: response.filesNames
});
return response.success;
}
}).catch((err) => {
console.error(err);
});
}
}
i hope this is helpful

React-Native 62.2 code image upload Error : network error

I am using React-Native two days back After React-Native version upgrading to 0-62.2, I encountered many problems.
Among them important one is image upload error getting [Error:Network error ]
Before upgrading the React-native my code is working fine
Below code is working fine for me for multiple image upload before upgrading to React-Native 0.62.2 but now i am getting [Error: Network error]
constructor() {
super();
this.state = {
uploadPercentage: 0,
}
}
// upload Files upload_Files = async () => {
upload_File() {
if (this.validate_Fields()) {
const { image, images, files, description, userId, size } = this.state;
console.log('AddPost Screen : upload_File:', 'userId:', userId, 'Files:', files, 'description:', description)
// this.setState({ error: '', loading: true });
if (this.state.type === 'image/jpeg') {
console.log('AddPost Screen : upload_ files :', files);
const formData = new FormData();
formData.append('user_id', userId);
formData.append('description', description);
// formData.append('files[]', files);
for (let i = 0; i < files.length; i++) {
formData.append('files[]', {
name: files[i].path.split('/').pop(),
type: files[i].mime,
uri: Platform.OS === 'android' ? files[i].path : files[i].path.replace('file://', ''),
});
}
// upload percentage progress bar ******************************************************
const options = {
onUploadProgress: (progressEvent) => {
const { loaded, total } = progressEvent;
let percent = Math.floor((loaded * 100) / total)
console.log(`${loaded}kb of ${total}kb | ${percent}%`);
if (percent < 100) {
this.setState({ uploadPercentage: percent })
}
}
}
axios.post(API_URL + '/fileuploadapi/uploadPost', formData, options, {
headers: { "Content-type": "multipart/form-data" }
}).then((response) => {
console.log(JSON.parse(JSON.stringify(response.status)));
// upload percentage progress
this.setState({ uploadPercentage: 100 }, () => {
setTimeout(() => {
this.setState({ uploadPercentage: 0 })
}, 1000);
})
this.cleanupImages();
Alert.alert('Upload Post Successfully');
}).catch((error) => {
console.log(error);
this.cleanupImages();
Alert.alert('image Upload Post Failed , Try again !');
});
}
}
}
// clear files data
cleanupImages() {
this.setState({
description: '',
image: null,
images: null,
// video: '',
files: '',
uploadPercentage: 0,
})
ImagePicker.clean().then(() => {
console.log('removed tmp images from tmp directory');
}).catch(error => {
alert(error);
});
}
If anyone know the solution please let me know ...
I just found the solution for the React-Native 62.2 upgrading error for image upload Error
[Error: network error]
Just remove the file "ReactNativeFlipper.java" from debug/java folder
File Location :
android/app/src/debug/java/com/appname/ReactNativeFlipper.java

Unable to share Image of Product in React Native Share

I am working on sharing the product description, url and image using react-native-share. But, it is not working and showing the attachment as somename.null.
I am getting the base64 image from response. Code is written below.
shareProduct = () => {
console.log(this.props.productDetails);
let { name, product_url, base64 } = this.props.productDetails;
const shareOptions = {
title: "Testing APP",
url: product_url,
message: "This is the testing. Please check",
subject: name
};
if( base64 !== "" && base64 !== undefined ){
shareOptions.url = base64;
shareOptions.type = 'image/jpeg';
}
Share.open(shareOptions)
.then(res => {})
.catch(err => {
console.log(err);
});
};
Please help me to find issue where I am wrong.
You need to change url in Options :
Share.open(
{
message: "This is the testing. Please check",
title: 'Share',
url: product_url,
type: 'image/jpg',
activityItemSources: [
{
linkMetadata: {image: `data:image/jpg;base64,${product_url}`},
},
],
},
{
// Android only:
dialogTitle: 'Share',
// iOS only:
excludedActivityTypes: ['com.apple.UIKit.activity.PostToTwitter'],
},
);