How can I reduce, compress <Image> size in axios fetch? - React Native - react-native

I get my products from API but photo sizes are really big. I want to compress them and reduce their sizes. I am sharing my get request and flatList. Any help will be appreciated!

You can use the manipulateAsync function of react-native-image-manipulator library.
You can use this example function:
import * as ImageManipulator from 'react-native-image-manipulator';
export const compressImage = async (uri) => {
const manipImage = await ImageManipulator.manipulateAsync(
uri, [], { compress: 0.3 }
);
return manipImage;
}
You can use the compress option to compress your photo.

Related

play audio using base64 string in react native

I have encoded audio in base64 string using react-native-fs. Now I want to decode base64 string back to audio format and play in react-native.
import RNFS from 'react-native-fs';
const [audioBase64,setAudioBase64]=React.useState(null)
RNFS.readFile(audioPath,"base64").then((res)=>setAudioBase64(res))
Now my base64 string is saved in audioPath.
By the way for playing sound, I am using react-native-sound and I couldn't find any format to play sound in react-native-sound using base64 data.
If anyone has experienced this and resolve the issue then kindly do let me know.
i some how want to do something similar,
i think first we need to write string base 64 and after that play it
like below:
const path = '${RNFS.DocumentDirectoryPath}/${attachment}.aac';
RNFS.writeFile(path, yourBase64String, 'base64').then(() => playSound())
const playSound = () => {
const sound = new Sound(path, '', () => callback(sound))
}
const callback = () => sound.play(successCallback)

How to compress image only when it's too large with react-native-image-picker

I'm using react-native-image-picker and I want to compress images in order to send them faster to my server.
Right now setting the option "quality" to 0.5 works just fine, but I don't want to compress small images too. I rather keep them untouched indeed.
How can I provide a condition which considers the current size of the file, then set the "quality" option to 0.5 , only if the size is larger than a specified amount (5MB for example)?
import ImagePicker from 'react-native-image-picker';
onPressGallery() {
const option = {
multiple: false,
width: 1000,
height: 500,
quality: 0.5,
};
ImagePicker.launchImageLibrary(option, response => {
{
console.log('onPressGallery', response);
const source = {uri: response.path};
}
});
}
I really appreciate it if anyone could help.
I am using the showImagePicker function returned from 'react-native-image-picker' and having the same problem. What i did was add the (maxHeight: 600, maxWidth: 800) and it works.
Response is returning bytes now, after that you can feed the image to ImageManipulator and apply the wished quality (compress prop from https://docs.expo.io/versions/v35.0.0/sdk/imagemanipulator/)

I want to generate a hash for a given video, in a react native app

I have a video file which has been recorded from the React-native App. Now I want to generate a digital signature, or a hash for this video file, and associate it to the blockchain. Is there any way I can create a hash for the video file in the React-native App?
You can use rnfs to hash files directly from storage.
You also can use a small package i wrote, react-native-hash, to hash directly from a URL, File or strings, how ever, it only works on Android for now.
You can use react-native-fetch-blob and js-sha3 module
After encoding your video file to base64, you can encrypt the base64 value using the hash module.
import RNFetchBlob from 'react-native-fetch-blob'
sha3_256 = require('js-sha3').sha3_256;
...
let data = ''
let hashdata = '';
RNFetchBlob.fs.readStream(
// file path
PATH_TO_THE_FILE,
// encoding, should be one of `base64`, `utf8`, `ascii`
'base64',
// (optional) buffer size, default to 4096 (4095 for BASE64 encoded data)
// when reading file in BASE64 encoding, buffer size must be multiples of 3.
4095)
.then((ifstream) => {
ifstream.open()
ifstream.onData((chunk) => {
// when encoding is `ascii`, chunk will be an array contains numbers
// otherwise it will be a string
data += chunk
})
ifstream.onError((err) => {
console.log('oops', err)
})
ifstream.onEnd(() => {
hashdata = sha3_256(data); // Convert Data to Hash Value
})
})
If use Expo
import * as DocumentPicker from 'expo-document-picker';
import * as FileSystem from 'expo-file-system';
sha3_256 = require('js-sha3').sha3_256;
const response: IDocumentPickerResponse = await DocumentPicker.getDocumentAsync({
copyToCacheDirectory: false,
type: '*/*',
});
const file: string = await FileSystem.readAsStringAsync(
response.uri,
{
encoding: FileSystem.EncodingTypes.Base64,
});
const hashdata = sha3_256(file); // Convert Data to Hash Value

How to hash image data in React-Native (Expo)?

My intent:
I want my app to upload images to S3. If image already exists, server should record a reference to existing image rather than asking for an upload of another copy.
How I imagine that works:
Hash image data
Send hash to server with request for signed url (to upload to AWS S3)
If hash matches something already stored, reference it and tell app
Initial thoughts:
Use imageEditor.cropImage to get image into ImageStore, which will give me an appropriate uri. Then use getBase64ForTag(uri, success, failure) to retrieve base64 data for a hash calculation.
The problem:
According to the answer on this question, this process is not efficient in the least. The usual solution would be to use native methods, as described in the answer to this question, however I do not want to eject my Expo app for this feature.
My Question:
Is there a better way to hash image data? Or more fundamentally, is there a better way of ensuring that identical images are not duplicated in S3 storage?
EDIT 2020-10-21 :
The library updated itself, and you should now call:
_hashImage = async (imageUri) => {
return await FileSystem.getInfoAsync(imageUri, { md5: true } );
}
ORIGINAL:
It turns out that Expo provides this out of the box.
Expo.FileSystem.getInfoAsync
myImageHashFunction = async (imageUri) => {
let fsInfo = await Expo.FileSystem.getInfoAsync(imageUri, [{ md5: true }] )
console.log(fsInfo.md5)
}
If you are still looking for a solution:
This is how I got it working - create a base64 of the image and then create a hash of it.
import * as FileSystem from 'expo-file-system';
import * as Crypto from 'expo-crypto';
let info = await FileSystem.readAsStringAsync(imageUri,
{ encoding: FileSystem.EncodingType.Base64 });
const hashData = await Crypto.digestStringAsync (
Crypto.CryptoDigestAlgorithm.MD5,
info
)

React Native Speed up converting image uri to base64

I'm working on a react native iOS app where I want to take certain images from a user's Camera Roll and save them in cloud storage (right now I'm using Firebase).
I'm currently getting the images off the Camera Roll and in order to save each image to the cloud I'm converting each image uri to base64 and then to a blob using the react-native-fetch-blob library. While this is working I am finding the conversion process to base64 for each image to be taking a very long time.
An example image from the Camera Roll:
What would be the most efficient/quickest way to take the image uri for each image from the Camera Roll, convert it, and store it to cloud storage.
Is there a better way I can be handling this? Would using Web Workers speed up the base64 conversion process?
My current image conversion process:
import RNFetchBlob from 'react-native-fetch-blob';
const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
window.Blob = Blob
function saveImages(images) {
let blobs = await Promise.all(images.map(async asset => {
let response = await convertImageToBlob(asset.node.image.uri);
return response;
}));
// I will then send the array of blobs to Firebase storage
}
function convertImageToBlob(uri, mime = 'image/jpg') {
const uploadUri = uri.replace('file://', '');
return new Promise(async (resolve, reject) => {
let data = await readStream(uploadUri);
let blob = await Blob.build(data, { type: `${mime};BASE64` });
resolve(blob);
})
}
function readStream(uri) {
return new Promise(async (resolve, reject) => {
let response = await fs.readFile(uri, 'base64');
resolve(response);
})
}
I found the solution below to be extremely helpful in speeding up the process. The base64 conversion now takes place on the native side rather than through JS.
React Native: Creating a custom module to upload camera roll images.
It's also worth noting this will convert the image to thumbnail resolution.
To convert an image to full resolution follow guillaumepiot's solution here:
https://github.com/scottdixon/react-native-upload-from-camera-roll/issues/1
I would follow the example here form the react-native-fetch docs. It looks like you're trying to add an extra step when they take care of that for you.
https://github.com/wkh237/react-native-fetch-blob#upload-a-file-from-storage