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

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.

Related

Show local image file:///tmp/someimage.jpg

Scenario
I'm contributing for a OSS project that is build on BlazorServerSide and ElectronNET.API Version 9.31.1.
In an Electron window we would like to show images from local storage UI via <img> tag.
What I have tried:
I have tried with:
<img src="file:///home/dani/pictures/someimage.jpg" />
But doesn't work. Image doesn't appear. I have then tried to create electron window with WebSecurity = false, but also doesn't help (images appears as broken on UI):
var browserWindowOptions = new BrowserWindowOptions
{
WebPreferences = new WebPreferences
{
WebSecurity = false,
},
};
Task.Run(async () => await Electron.WindowManager.CreateWindowAsync(
browserWindowOptions,
$"http://localhost:{BridgeSettings.WebPort}/Language/SetCultureByConfig"
));
Finally, as workaround, I'm sending the images as data base64 in img src's attribute, but it looks like a dirty approach.
My Question:
My question is, how can I show on electron window picture files from local storage.
Some irrelevant info:
The open source line where I need assistance.
There are several ways to go about this, so I will try to cover the most relevant use cases. Some of this depends on the context of your project.
Access to local files behave as cross origin requests by default. You could try using the crossorigin=anonymous attribute on your image tag, but doesn't work because your local file system will not be responding with cross origin headers.
Disabling the webSecurity option is a workaround, but is not recommended for security reasons, and will not usually work correctly anyway if your html is not also loaded from the local file system.
Disabling webSecurity will disable the same-origin policy and set allowRunningInsecureContent property to true. In other words, it allows the execution of insecure code from different domains.
https://www.electronjs.org/docs/tutorial/security#5-do-not-disable-websecurity
Here are some methods of working around this issue:
1 - Use the HTML5 File API to load local file resources and provide the ArrayBuffer to ImageData to write the image to a <canvas> .
function loadAsUrl(theFile) {
var reader = new FileReader();
var putCanvas = function(canvas_id) {
return function(loadedEvent) {
var buffer = new Uint8ClampedArray(loadedEvent.target.result);
document.getElementById(canvas_id)
.getContext('2d')
.putImageData(new ImageData(buffer, width, height), 0, 0);
}
}
reader.onload = putCanvas("canvas_id");
reader.readAsArrayBuffer(theFile);
}
1.b - It is also possible to load a file as a data URL. A data URL can be set as source (src) on img elements with JavaScript. Here is a JavaScript function named loadAsUrl() that shows how to load a file as a data URL using the HTML5 file API:
function loadAsUrl(theFile) {
var reader = new FileReader();
reader.onload = function(loadedEvent) {
var image = document.getElementById("theImage");
image.setAttribute("src", loadedEvent.target.result);
}
reader.readAsDataURL(theFile);
}
2 - Use the Node API fs to read the file, and convert it into a base64 encoded data url to embed in the image tag.
Hack - Alternatively you can try loading the image in a BrowserView or <webview>. The former overlays the content of your BrowserWindow while the latter is embedded into the content.
// In the main process.
const { BrowserView, BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600 })
const view = new BrowserView()
win.setBrowserView(view)
view.setBounds({ x: 0, y: 0, width: 300, height: 300 })
view.webContents.loadURL('file:///home/dani/pictures/someimage.jpg')

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

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.