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

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/)

Related

How can I reduce, compress <Image> size in axios fetch? - 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.

Property 'base64Data' does not exist on type 'CameraPhoto' in Ionic4 using capacitor

I was following a tutorial where for uploading a picture from native application they choose resultType as CameraResultType.Base64 and then got the base64Data from that image and finally convert that to filestream. But in my case base64Data this property was not available. I want to know what is wrong with my code. Here is my code snippet:
import {Plugins, Capacitor, CameraSource, CameraResultType} from '#capacitor/core';
Plugins.Camera.getPhoto({
quality: 50,
source: CameraSource.Prompt,
correctOrientation: true,
height: 320,
width: 320,
resultType: CameraResultType.Base64
}).then(image => {
this.selectedImage = image.base64Data;
}).catch(err =>{
console.log(err);
});
I need to upload the image as file stream. Is there any other way to get the filestream from the taken image or webpath? If anyone know the work around please let me know. I already ran 'ionic capacitor update' command to make sure my capacitor is up-to-date
You are following an out of date tutorial, base64Data was removed before the final release.
You can use base64String instead, but note that base64String is just the base64 representation of the image, if you want a data url that can be used as a img src you should use CameraResultType. DataUrl and image.dataUrl

User cannot upload image of file size more than 4MB image

user should not upload image
file size should not be more than 4MB
takePicture() { //camera option(take image with camera)
const options: CameraOptions = {
quality: 70,
destinationType: this.camera.DestinationType.DATA_URL,
sourceType: this.camera.PictureSourceType.CAMERA,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum:false
}
this.camera.getPicture(options).then((imageData) => {
this.base64Image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
console.log(err)
});
}
You shouldn't use base64 for the image. This is because it will crash the app on older devices by using too much memory.
The better solution is to save it to file.
Your 4mb upload limit is not related to the camera plugin though.
You need a different plugin to resize the image.
You might want to try this one:
Image Resizer - Ionic Documentation
However, from a few searches, I cannot find any plugins that will resize to a certain target file size. They only handle dimensions and image quality changes.
Resizing the image is quite straightforward:
import { ImageResizer, ImageResizerOptions } from '#ionic-native/image-resizer/ngx';
constructor(private imageResizer: ImageResizer) { }
...
let options = {
uri: uri,
folderName: 'Protonet',
quality: 90,
width: 1280,
height: 1280
} as ImageResizerOptions;
this.imageResizer
.resize(options)
.then((filePath: string) => console.log('FilePath', filePath))
.catch(e => console.log(e));
To meet your file size requirement I would do two additional things:
Experiment to see what sort of dimensions/quality ratings produce images around 4mb
Consider adding a file size check which will loop and keep dropping resizing options that lower the quality / compress it more until it meets your file size requirement.
The thing is that the output filesize also depends on the type of image. Complicated images are hard to compress so the same dimensions + compression ratio = different sizes for different images.
So that's why the second bit might be required. Alternatively, you could just set a resize that is normally around 3mb to give you enough buffer. This would probably be best as resizing the image 3-4 times to get down to a target file size could be slow for the user.

How to update only the cloudinary Image of a User model?

There is not code which demonstrate the update of clodinary Image.
The code I have written below do update the Image but then I can not immediately use the FIll, or limit method of cloudinary Image.
cloudinary.uploader.upload(req.files.icon.path, function(img, err) {
console.log(img)
if(err){
res.send(err);
}else{
req.user.update({$set: {icon: img}}, function (err, count) {
res.send(img.fill(300,300));// this line says fill not defined.
//res.send(_img.fill(300,300));// this also fails
});
}
});
Note that the img that's returned isn't the actual image, it's a result JSON of the image's details.
Also, please have a look at the documentation to see how transformations are generated. Specifically, to apply a 300x300 fill crop, you need to add c_fill,h_300,w_300 to the URL, which could be achieved with something similar to:
cloudinary.image(img.public_id, { format: "jpg", width: 100, height: 150, crop: "fill" })

how to save the generated QR-code using react-native-qrcode

I am trying to generate QR code, by using this module 'react-native-qrcode', Here I got generated QR code like this, How can I save this QR code.
Can anyone give me suggestions that how to save this generated qr,any help much appreciated
The library you use uses a webview, therefore you have no image you may save. To save the QR code in a conceptional fashion you may store the value provided and put it into the component as you would like to display it. If you need to get the image, you would need to extend the webview javascript part to use the ImageData interface of the canvas. This is IMHO quite tricky and I am not entirely sure if it is even possible to get data back from the web view.
Use rn-qr-generator to generate a QR code. It will return a path or base64 of generated Image. Later you can use CameraRoll module to store the image in CameraRoll (or Gallery on android).
import RNQRGenerator from 'rn-qr-generator';
import CameraRoll from "#react-native-community/cameraroll";
RNQRGenerator.generate({
value: 'your_qr_string_value_here',
height: 100, // height of the output image
width: 100, // width of the output image
base64: false, // default 'false'
backgroundColor: 'black', // default 'white'
color: 'white', // default 'black'
})
.then(response => {
const { uri, width, height, base64 } = response;
this.setState({ imageUri: uri });
CameraRoll.save(uri);
})
.catch(error => console.log('Cannot create QR code', error));
Before calling CameraRoll.save make sure you have permission to save the image. Permission example see here.