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

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.

Related

In React Native / Expo, is there any way to save a specific part of an image?

From some research, I've figured out that expo libraries like takePicturesAsync() are able to take a picture and save it to the app's cache. However, the default state for libraries like these is to save the whole image. Is there any way for me to save a specific part of the image (e.g. the 2500 pixels at the center of the screen)?
Thanks!
You can use the onPictureSaved event to grab & manipulate the image.
takePicture = () => {
if (this.camera) {
this.camera.takePictureAsync({ onPictureSaved: this.onPictureSaved });
}
};
onPictureSaved = photo => {
console.log(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

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

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" })

React Native Retrieve Actual Image Sizes

I would like to be able to know the actual size of a network-loaded image that has been passed into <Image /> I have tried using onLayout to work out the size (as taken from here https://github.com/facebook/react-native/issues/858) but that seems to return the sanitised size after it's already been pushed through the layout engine.
I tried looking into onLoadStart, onLoad, onLoadEnd, onProgress to see if there was any other information available but cannot seem to get any of these to fire. I have declared them as follows:
onImageLoadStart: function(e){
console.log("onImageLoadStart");
},
onImageLoad: function(e){
console.log("onImageLoad");
},
onImageLoadEnd: function(e){
console.log("onImageLoadEnd");
},
onImageProgress: function(e){
console.log("onImageProgress");
},
onImageError: function(e){
console.log("onImageError");
},
render: function (e) {
return (
<Image
source={{uri: "http://adomain.com/myimageurl.jpg"}}
style={[this.props.style, this.state.style]}
onLayout={this.onImageLayout}
onLoadStart={(e) => {this.onImageLoadStart(e)}}
onLoad={(e) => {this.onImageLoad(e)}}
onLoadEnd={(e) => {this.onImageLoadEnd(e)}}
onProgress={(e) => {this.onImageProgress(e)}}
onError={(e) => {this.onImageError(e)}} />
);
}
Thanks.
Image component now provides a static method to get the size of the image. For example:
Image.getSize(myUri, (width, height) => {this.setState({width, height})});
You can use resolveAssetSource method from the Image component :
import picture from 'pathToYourPicture';
const {width, height} = Image.resolveAssetSource(picture);
This answer is now out of date. See Bill's answer.
Image.getSize(myUri, (width, height) => { this.setState({ width, height }) });
Old Answer (valid for older builds of react native)
Ok, I got it working. Currently this takes some modification of the React-Native installation as it's not natively supported.
I followed the tips in this thread to enabled me to do this.
https://github.com/facebook/react-native/issues/494
Mainly, alter the RCTNetworkImageView.m file: add the following into setImageURL
void (^loadImageEndHandler)(UIImage *image) = ^(UIImage *image) {
NSDictionary *event = #{
#"target": self.reactTag,
#"size": #{
#"height": #(image.size.height),
#"width": #(image.size.width)
}
};
[_eventDispatcher sendInputEventWithName:#"loaded" body:event];
};
Then edit the line that handles the load completion:
[self.layer removeAnimationForKey:#"contents"];
self.layer.contentsScale = image.scale;
self.layer.contents = (__bridge id)image.CGImage;
loadEndHandler();
replace
loadEndHandler();
with
loadImageEndHandler(image);
Then in React-Native you have access to the size via the native events. data from the onLoaded function - note the documentation currently says the function is onLoad but this is incorrect. The correct functions are as follows for v0.8.0:
onLoadStart
onLoadProgress
onLoaded
onLoadError
onLoadAbort
These can be accessed like so:
onImageLoaded: function(data){
try{
console.log("image width:"+data.nativeEvents.size.width);
console.log("image height:"+data.nativeEvents.size.height);
}catch(e){
//error
}
},
...
render: function(){
return (
<View style={{width:1,height:1,overflow='hidden'}}>
<Image source={{uri: yourImageURL}} resizeMode='contain' onLoaded={this.onImageLoaded} style={{width:5000,height:5000}} />
</View>
);
}
Points to note:
I have set a large image window and set it inside a wrapping element of 1x1px this is because the image must fit inside if you are to retrieve meaningful values.
The resize mode must be 'contain' to enable you to get the correct sizes, otherwise the constrained size will be reported.
The image sizes are scaled proportionately to the scale factor of the device, e.g. a 200*200 image on an iPhone6 (not 6 plus) will be reported as 100*100. I assume that this also means it will be reported as 67*67 on an iPhone6 plus but I have not tested this.
I have not yet got this to work for GIF files which traverse a different path on the Obj-C side of the bridge. I will update this answer once I have done that.
I believe there is a PR going through for this at the moment but until it is included in the core then this change will have to be made to the react-native installation every time you update/re-install.
TypeScript example:
import {Image} from 'react-native';
export interface ISize {
width: number;
height: number;
}
function getImageSize(uri: string): Promise<ISize> {
const success = (resolve: (value?: ISize | PromiseLike<ISize>) => void) => (width: number, height: number) => {
resolve({
width,
height
});
};
const error = (reject: (reason?: any) => void) => (failure: Error) => {
reject(failure);
};
return new Promise<ISize>((resolve, reject) => {
Image.getSize(uri, success(resolve), error(reject));
});
}