Cordova Camera iOS Issue: NOT_FOUND_ERR - ios

I am using the cordova-plugin-camera cordova plugin (version 4.0.3), wrapped by the Ionic Native wrapper for Ionic 4 #ionic-native/camera#4. I'm using it to capture a photo (regular or from library), and move it into my app storage area for saving/sending. Things work great on Android. On iOS I continue to get a NOT_FOUND_ERR back when trying to grab the FILE_URI that comes back from the capture.
Below is how I'm capturing the image, which works just fine. The camera launches, I snap (or choose) a photo, and I get a file URI back (file:///var/mobile/Containers/Data/Application/{guid}/tmp/XYZ.jpg). Then something as simple as doing a resolveLocalFilesystemUrl on this resulting file URI will bomb with NOT_FOUND_ERR. Any advice?
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: (isFromLibrary) ? this.camera.PictureSourceType.PHOTOLIBRARY : this.camera.PictureSourceType.CAMERA,
saveToPhotoAlbum: false,
targetWidth: (isForDocScan) ? desiredWidth + 500 : desiredWidth,
targetHeight: (isForDocScan) ? desiredHeight + 500 : desiredHeight
}
let result = null;
try {
result = await this.camera.getPicture(options);
}
catch (err) {
this.loggingService.error('Error getting photo', err);
}

You seem to have some hiccups when using the Camera.DestinationType configs. The below are the outputs when you use FILE_URI and NATIVE_URI
Camera.DestinationType.FILE_URI
'file://' ios
'content://' android
Camera.DestinationType.NATIVE_URI
'assets-library://' ios
'content://' android
Although this is the outputs, this is internally related to your sourceType. What this means is that, if your sourceType is the camera, you should be using FILE_URI as the output is obtained from the temporary storage, while if you are using photogallery, your output needs to be obtained from the library, which is why its recommended you use NATIVE_URI

Related

Ionic cordova camera plugin crashes intermittently after a picture is taken (with Firebase image upload)

uploadImage(filePath: string, camera: boolean = false) {
try {
let options: CameraOptions;
if (camera) {
options = {
quality: 40,
destinationType: this._camera.DestinationType.DATA_URL,
encodingType: this._camera.EncodingType.JPEG,
mediaType: this._camera.MediaType.PICTURE,
correctOrientation: true
}
} else {
options = {
destinationType: this._camera.DestinationType.DATA_URL,
sourceType: this._camera.PictureSourceType.PHOTOLIBRARY,
encodingType: this._camera.EncodingType.JPEG,
mediaType: this._camera.MediaType.PICTURE
}
}
this._camera.getPicture(options).then((imageData) => {
const photo = `data:image/jpeg;base64,${imageData}`;
const fileRef = this._afs.ref(filePath);
const task = fileRef.putString(photo, 'data_url');
task.snapshotChanges().pipe(
finalize(() => {
// execute other actions
fileRef.getDownloadURL().subscribe(url => {
if (url) {
this.fileUploadUrl.next(url);
}
})
let toast = this.toastCtrl.create({
message: 'Image upload successfully',
position: 'bottom',
duration: 3000
});
toast.present();
})
).subscribe();
})
} catch (e) {
console.error(e);
let toast = this.toastCtrl.create({
message: 'Image upload cancelled',
position: 'bottom',
duration: 3000
});
toast.present();
}
}
After a picture a taken (from actual iOS device) sometimes it crashes, sometimes it works fine. If I use the front camera, it always work.
But if I use the back camera, after a picture a selected, it flashes a white screen and then the app restarts. I suspect if it’s something to do with the image size or resolution. Sometimes if I take a very low res picture with the back camera (like in a low light environment), it uploads just fine. I researched a bit online, some people suggest running the app with production mode with --prod flag, but it is not solving it.
I also tried to lower the quality value to a lower number, but that still doesn’t work with the back camera.
I am pretty sure the plugin is added correctly and the privacy settings are also correct otherwise it won't allow me to take pictures.
Yes, you are right. When taking picture using camera with DataURL (i.e Base64). we may face memory issue because of the picture size and quality. You have quality of '40' with is fine. For Width and height you can set around 300px.
The more the image size will increase the size of the image which will impact the memory.
It's not the proper solution for your query, but after wasting my nights on the same I tried to reduce the image and tried to maintain it less than 2mb and it worked quite well.You can reduce the image size by giving the targetWidth and targetHeight. I kept both of them below 500.
const options: CameraOptions = {
quality: 30, // picture quality
destinationType: this.camera.DestinationType.DATA_URL,
sourceType: this.camera.PictureSourceType.CAMERA,
encodingType: this.camera.EncodingType.PNG,
mediaType: this.camera.MediaType.PICTURE,
cameraDirection: this.camera.Direction.FRONT,
allowEdit: true,
correctOrientation :false,
targetWidth: 400,
targetHeight: 400,
}

Avoid iOS video compression with Cordova camera.getPicture()

Is there a way to avoid the iOS video compression when selecting a video from the gallery with camera.getPicture()?
var options = {
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
mediaType: 1
}
navigator.camera.getPicture(videoGallerySuccess, videoGalleryError, options);
The user has to wait for the video compression to be finished when selecting a video.
I would like to avoid this and instead do my own compression whenever the user has submitted a form for example.
In Cordova Camera Plugin you need to define a quality of the final video/photo. According documentation, default value for all media types is 50. To prevent a loss of resolution (and potentially video processing) set quality to 100.
var options = {
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
mediaType: 1,
quality: 100
}
navigator.camera.getPicture(videoGallerySuccess, videoGalleryError, options);

Recieve a Memory warning iOS after using camera with Cordova

When I take a photo, I begin to receive memory warnings continuously. I'm using Cordova 3.5 and the camera plugin with these settings.
var _config;
var pictureSource;
var destinationType; // sets the format of returned value.
var encodingType; // enconding type 0=JPG 1=PNG
/**
* Initialize camera plugin.
* #param {object} config - settings.
*/
function initialize(config) {
alert("CAMERA is comming!!");
// Wait for Cordova to connect with the device
document.addEventListener('deviceready', onDeviceReady, false);
}
/**
* Cordova is ready to be used!
* #param {object} config - settings.
*/
function onDeviceReady() {
console.log("CAMERA is READY!!");
pictureSource=navigator.camera.PictureSourceType;
destinationType=navigator.camera.DestinationType;
encodingType = navigator.camera.EncodingType;
capturePhoto();
}
/**
* Set camera plugin settings.
* #param {object} config - settings.
*/
function setConfig(config) {
_config = config;
}
/**
* Take picture using device camera and retrieve image as base64-encoded string.
*/
function capturePhoto() {
setConfig({ quality: 20, destinationType: destinationType.DATA_URL, encodingType: 0});
navigator.camera.getPicture(onPhotoDataSuccess, onFail, _config);
}
/**
* Photo is successfully retrieved.
* #callback getPicture~onPhotoDataSuccess
* #param {string} imageData - A base64-encoded image.
*/
function onPhotoDataSuccess(imageData) {
//Edit photo
}
I make sure that the quality is low, but it gets slower until it crashes.
Thanks for all the help!
Finally, I solved the problem by fixing the photo size:
/**
* Take a picture and get the image as base64-encoded string.
*/
function capturePhoto() {
setConfig({ quality: 20, targetWidth: 600, targetHeight: 600, correctOrientation: true, destinationType: destinationType.DATA_URL, encodingType: 0});
navigator.camera.getPicture(onPhotoDataSuccess, onFail, _config);
}
DATA_URL returns the image as a data stream. Modern, High Resolution cameras simply overload the JavaScript engine because of the size of the string value being returned to the program. From my Apache Cordova API Cookbook:
"There are issues with using Camera.DestinationType.DATA_URL. The camera image contains a lot of data, and converting the image to a string and passing it to a Cordova application to work with exceeds the limits of most any device’s JavaScript engine. Unless you crank down the quality or size of the image, you will most likely find that the application is very slow or crashes when you use this option."
Recommendation is to use FILE_URI instead, you'll never be able to use DATA_URL unless you take very small photos.

Photo captured from Ipad will be inverted at server

I am developing an application in phonegap and have functionality of photo capturing using Ipad camera, It works fina and all photo saved properly on server. the only issue was with the fact that they are rotated 90 degree left while saved on server.
Now i tried same thing for photos stored in library and they are upload as it is on server, so i think issue is with ipad photo capturing process. Can anyone help me to found solution for such problem. Is it Ipad normal behaviour or i have mistaken in code ?
I have used below function for photo functionality
//Capture Photo either from camera or IPAD library
function capturePhoto(source){
var deferred = $q.defer();
//When source == 1 than from Photo Library
var cameraOptions = { quality: 70, destinationType: Camera.DestinationType.FILE_URI };
if(source == 1){ cameraOptions = { quality: 70, destinationType: Camera.DestinationType.FILE_URI, sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY,targetWidth: 600,targetHeight: 600 }; }
navigator.camera.getPicture( function (imageURI) {
window.resolveLocalFileSystemURI(imageURI, function (fileEntry) {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
fileSys.root.getDirectory("auditPhotos", {create: true, exclusive: false}, function(dir) {
fileEntry.copyTo(dir,generateRandomID()+".jpg",function (entry) {
deferred.resolve(entry.fullPath)
}, null);
}, null);
}, null);
},null);
},
function (message) {
deferred.reject(message);
},
cameraOptions
);
//deferred.resolve(generateRandomID()+".jpg");
return deferred.promise;
}
As you are saving captured image (Using above function) on server in jpg format. JPG & JPEG's have a property of EXIF which store orientation of image. When you captured image through IPAD, this exif data stores camera orientation and other position related things. But this are understood by ipad only and not by browser, that's why image was seen rotated in browser which is the truth. And same image when you viewed in IPAD it was set by IPAD in proper position due to availablity of EXIF.
To solve this problem just save your image in PNG format instead of JPG and all works fine :-)
My friend had a similar problem recently, and while I'm not too sure how to specifically solve your problem, I do know that EXIF data on the image should store something about how it's oriented.
You can try implementing this library to get the EXIF data and rotate the image if needed before the upload: https://code.google.com/p/iphone-exif/

Phonegap/ios - Capture video not saving to iPhone camera roll

When taking a video in the app the video is not saved to camera roll.
I have set the flag saveToPhotoAlbum: true.
My code
opt = {
limit: 1,
saveToPhotoAlbum: true,
quality: 1
};
navigator.device.capture.captureVideo(
that.captureVideoOnSuccess,
that.onCaptureFail,
opt
);
A similar code works for getPicture with no problems
navigator.camera.getPicture(
that.uploadPhoto,
that.onCaptureFail, {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
mediaType: Camera.MediaType.PICTURE,
saveToPhotoAlbum: true
}
);
Any idea how to over come this?
Any solution will be welcome - by config, js code, Objective-C
Thanks
Here is my solution (based on https://groups.google.com/forum/#!topic/phonegap/245nKJoqqak)
In plugins/org.apache.cordova.media-capture/src/ios/CDVCapture.m
Method - (CDVPluginResult*)processVideo:(NSString*)moviePath forCallbackId:(NSString*)callbackId
Uncomment the lines under
/* don't need, it should automatically get saved
I don't know why those line are comment out...

Resources