React Native - How to rename camera roll image file name - react-native

I'm having a problem using #react-native-community/cameraroll.
Here's my code:
const handleSaveImageToDevice = async () => {
try {
const uri = await captureRef(viewRef, {
format: 'jpg',
quality: 0.8,
});
const image = CameraRoll.save(uri, {
type: 'photo',
album: 'Generated Image',
});
} catch (e) {
return e;
}
};
As seen in the code I used captureRef to save react elements with ref as image.
The behavior is working as expected. If the user clicks the save button the image will be saved to the designated folder. But the problem is it saves random file name. I want to rename it like for example "generated_image".

When you are capturing there is option for image file name:
const uri = await captureRef(viewRef, {
format: 'jpg',
quality: 0.8,
fileName: 'generated_image'
});
Refer below link:
https://github.com/gre/react-native-view-shot/issues/116#issuecomment-1155523609

I forgot to update this but I already found a way to fix my problem using third party library react-native-fs
viewShot?.current?.capture().then((data) => {
RNFS.writeFile(
RNFS.CachesDirectoryPath +
`/generated-image.jpg`,
data,
'base64',
).then((success) => {
return CameraRoll.save(
RNFS.CachesDirectoryPath +
`/generated-image.jpg`,
{
type: 'photo',
album: 'testing',
},
);
});
});

Related

React Native Share app icon not showing on share sheet

I have set up react-native-share with RN .68.1 and the latest of react-native-share, and everything works great except for the app icon is not showing. The documentation doesn't really explain it very well.
My share code:
const handleShare = (title: string, url: string) => {
const parsedTitle = HtmlTextParser(title);
const shareOptions = Platform.select({
ios: {
title: parsedTitle ?? '',
message: parsedTitle,
url: `https://testUrl.com${url}`,
},
default: {
title: parsedTitle ?? '',
message: parsedTitle,
url: `https://testUrl.com${url}`,
},
});
try {
const share = Share.open({...shareOptions, failOnCancel: false});
} catch (e) {
console.log('error: ', e);
}
};
Can I set a custom icon here easily? Is there a working example somewhere that I can consult to make this happen?

I am converting Images to pdf using a npm library in react native why it is giving error of null object?

I am using react-native-image-to-pdf library to convert images to pdf in my react native app. from https://www.npmjs.com/package/react-native-image-to-pdf
var photoPath = ['https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350','https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350'];
const myAsyncPDFFunction = async () => {
try {
const options = {
imagePaths: photoPath,
name: 'PDFName',
};
const pdf = await RNImageToPdf.createPDFbyImages(options);
console.log(pdf.filePath);
} catch(e) {
console.log(e);
}
}
but this is giving error Error: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
I have also tried giving path as ['./assets/a.png', './assets/b.png']
but still getting same error
Based on the usage example, your photoPath needs to be a local file path and not a remote path.
My recommendation is to first use rn-fetch-blob to download the remote image to the device, and then pass your new local image path to react-native-image-to-pdf. Something like:
RNFetchBlob
.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
fileCache : true,
})
.fetch('GET', 'http://www.example.com/file/example.png', {
//some headers ..
})
.then(async (res) => {
// the temp file path
console.log('The file saved to ', res.path())
const options = {
imagePaths: [res.path()],
name: 'PDFName',
};
const pdf = await RNImageToPdf.createPDFbyImages(options);
})
from file path remove the text 'file://; with empty string('').
const options = {
imagePaths: [uri.replace('file://', '')],
name: 'FileName',
quality: .9, // optional compression paramter
};
replace('file://', '') it's work for me

Expo Document picker does not give back the correct uri

So I am trying to use the expo document picker (https://docs.expo.io/versions/latest/sdk/document-picker/) to let the user select an image from their phones file system and display it on the screen. It was working quite recently until I noticed that the promise it sends back stopped returning the correct uri. Before it was returning a uri starting with file:///data/ where as now it returns a uri starting with /data. This new type of uri does not display on the screen and I am wondering how I get back to the old one? I am using await DocumentPicker.getDocumentAsync to get the file in the first place.
I had the exact same problem after upgrading from expo 38 to 42. I did a workaround using expo-file-system.
First I set the copyToCacheDirectory option to false
const result = await DocumentPicker.getDocumentAsync({
type:'*/*',
copyToCacheDirectory: false,
});
That would save the file to the conten:// file space. Once we have the file we can copy it to our file:// location:
const uri = FileSystem.documentDirectory+result.name;
await FileSystem.copyAsync({
from: result.uri,
to: uri
})
Now you should be able to use uri (which includes the file:// path) without problems.
I have same problem from expo SDK 38 to SDK 42,
I find a workaround from here
const encode = uri => {
if (Platform.OS === 'android') return encodeURI(`file://${uri}`)
else return uri
}
...
<Button
onPress = { async () => {
let result = await DocumentPicker.getDocumentAsync({ type: '*/*' })
if (result.type === "success") {
console.log("getDocumentAsync", result);
Alert.alert(
"upload file",
`Whether to upload ${result.name}`,
[
{
text: "Cancel",
onPress: () => {},
style: "cancel"
},
{
text: "OK",
onPress: () => dispatch(action.sendFile(encode(result.uri)))
}
],
{ cancelable: true }
)
}
}}
/>
it work for me!
I you want the file to be accessible for using in WebView, You can do this
const result = await DocumentPicker.getDocumentAsync({
type: "application/pdf",
copyToCacheDirectory: false,
});
This is will give you a uri like this
{
...,
"uri": "content://com.android.externalstorage.documents/document/home%3Ayour-file.pdf",
}
and you can access the file by passing it as uri
{{
uri: uri,
}}

how to implement an image and pdf picker in one single upload button in expo?

I am building a mobile app by using EXPO.Now i am stucked in a img & pdf picker,i can't pick image and pdf in one single function or button. can anyone know any packages that enable pdf & image picker in one function.....
You can use expo document picker to pick multiple file types and images as following:
import * as DocumentPicker from 'expo-document-picker';
const picker = await DocumentPicker.getDocumentAsync({
type: "*/*",
multiple: true,
copyToCacheDirectory: true
});
Check the official expo docs DocumentPicker
If you wanna allow your user to select pdf then you can do this
async function openDocumentPicker() {
try {
const res = await DocumentPicker.getDocumentAsync({
type: "*/*",
copyToCacheDirectory: true,
multiple: false,
});
console.log(res)
var lastThree = res.name.substr(res.name.length - 3);
if(lastThree == 'pdf')
{
if(res.type == 'success')
{
//Do Something here
}
}
else
{
alert('Please select PDF File')
}
} catch (error) {
alert(error);
}
}

How to get jpg image from heic format in react native

I am picking photos from gallery and upload to server but since few days I noticed that some photos have extension heic and browsers can't render those images.
1. Is there a way to extract photos from uploaded heic?
2. How in react native I can get jpeg from this format?
You can convert it on the server side, with the help of this awesome lib Tifig.
https://github.com/monostream/tifig
You can also use API's like https://cloudconvert.com/formats/image/heic to convert either on server side or on the mobile (client side).
I'm assuming you are using react-native-image-picker, which is the community library and most used one.
Actually is not necessary to install another module, just grab always the uri from the response and update the filename in case you are having a heic image. Code example:
const options = {
title: 'Select Avatar',
storageOptions: {
skipBackup: true,
path: 'images'
},
noData: true,
quality: 1,
mediaType: 'photo'
};
ImagePicker.showImagePicker(options, imgResponse => {
this.setState({ imageLoading: true, avatarMediaId: null });
if ((imgResponse.didCancel) || (imgResponse.error)) {
this.setState({ imageLoading: false });
} else {
let source = {};
let fileName = imgResponse.fileName;
if (Platform.OS === 'ios' && (fileName.endsWith('.heic') || fileName.endsWith('.HEIC'))) {
fileName = `${fileName.split(".")[0]}.JPG`;
}
source = { uri: imgResponse.uri, fileName };
this.uploadImage(source);
}
});
Here's my solution: I am using react-native-image-crop-picker.
In my case, the server doesn't accept if a filename is .HEIC, telling me to use .png or .jpg
So I just:
image.filename.replace(/HEIC/g, 'jpg')
To give you a whole picture:
const formData = new FormData();
formData.append('file', {
uri: image.path,
name: image.filename.replace(/HEIC/g, 'jpg'),
type: image.mime,
});
return await axios.post(`/avatar/${id}`, formData);