I'm having a couple of issues I tell them. I am taking a picture with the plugin Camera with phonegap and that suits me, what I do with that image is about putting another picture above I'm doing it through canvas and the problem is this left images to make it look. Zoom or something applied.
Original image
https://scontent-mia.xx.fbcdn.net/hphotos-xpf1/v/t1.0-9/10987455_403839709795958_6331116352644016645_n.jpg?oh=df8fc2cef2c1255a6babec94b3a2056d&oe=557E3520
Canvas image
https://scontent-mia.xx.fbcdn.net/hphotos-xpf1/v/t1.0-9/11064814_403839689795960_2255378534429169909_n.jpg?oh=9c0ebab7c6e9911cc28695fa80cc3033&oe=5581D16B
Also, when I take photos I can not take it whole, something I do not understand that there will be cutting the image.
Here's the setup method camera and canvas.
$scope.guardarFoto = function(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("img_foto");
var img2 = document.getElementById("img_foto2");
ctx.drawImage(img,0,0);
ctx.drawImage(img2,0,0);
window.canvas2ImagePlugin.saveImageDataToLibrary(
function(msg){
console.log(msg);
},
function(err){
console.log(err);
},
document.getElementById('myCanvas')
);
}
Camera.DestinationType = {
DATA_URL : 0, // Return image as base64-encoded string
FILE_URI : 1, // Return image file URI
NATIVE_URI : 2 // Return image native URI (e.g., assets-library:// on iOS or content:// on Android)
};
Camera.PictureSourceType = {
PHOTOLIBRARY : 0,
CAMERA : 1,
SAVEDPHOTOALBUM : 2
};
Camera.EncodingType = {
JPEG : 0, // Return JPEG encoded image
PNG : 1 // Return PNG encoded image
};
Camera.MediaType = {
PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
VIDEO: 1, // allow selection of video only, WILL ALWAYS RETURN FILE_URI
ALLMEDIA : 2
};
Camera.Direction = {
BACK : 0, // Use the back-facing camera
FRONT : 1 // Use the front-facing camera
};
$scope.getPhoto = function() {
var options = {
quality: 100,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: true,
correctOrientation: true
};
Camera.getPicture(options).then(function(imageURI) {
console.log(imageURI);
$scope.lastPhoto = imageURI;
}, function(err) {
// error
});
};
Related
We have an app, created with React Native, where the user can take a picture and save it to his account. So we are sending the photo to our server. The problem is, that this takes really much time (about 20 to 30 seconds) on iOS. With the Android-Build it is much faster (about 2 seconds).
We have tried to reduce the quality of the pictures, but that has also not a big effect.
takePicture = async function(camera) {
const options = {
quality: 0.5,
fixOrientation: true,
forceUpOrientation: true
};
const data = await camera.takePictureAsync(options);
this.props.onCapture(data);
};
We would like to achieve the same uploading-time like on Android. Can someone help?
I've written the following function. After taking image it returns the original and resized image which takes around 500KB on iOS.
It uses ImagePicker package.
const pickImage = async (index) => {
const { status: cameraPerm } = await Permissions.askAsync(Permissions.CAMERA);
const { status: cameraRollPerm } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
import * as ImagePicker from 'expo-image-picker'
if (cameraPerm === "granted" && cameraRollPerm === "granted") {
let pickerResult;
if (index == 0 || index == undefined) {
pickerResult = await ImagePicker.launchCameraAsync({ allowsEditing: false, aspect: [4, 3], quality: 1 });
}
else if (index == 1) {
pickerResult = await ImagePicker.launchImageLibraryAsync({ allowsEditing: false, aspect: [4, 3], quality: 1 });
}
if (!pickerResult.cancelled) {
let resizedImage = await ImageManipulator.manipulateAsync(
pickerResult.uri, [{ resize: { width: 1200 } }],
{ compress: 1, format: "jpg", base64: false });
return [resizedImage.uri, pickerResult.uri];
} else {
return
}
} else {
alert(Messages.userManagement.cameraPermissions);
return
}
Then you can call above method like this.
let [resizedImage, originalImage] = await pickImage();
I'm building a hybrid app in ionic, which runs over cordova. I use the $cordovaCamera plugin to capture images from the phone, either by selecting from the phone's gallery or by using the camera to take a picture.
I then send that image using Restangular to my server, and when that action finishes, I want to display a status message on the screen.
My problem: All of the above works perfectly on Android. On iOS, it is working only when the image is selected from the gallery, but not when the image is directly captured from the phone. In that case, the image is correctly transferred to the server, the request returns a 201 Created just as it should - but the then() callback function is never entered.
If anyone can explain this behavior, that would be awesome...my second best would be to capture the image on the iPhone, save to gallery, and then attempt to retrieve the last saved image, but I haven't been able to figure out how to yet and I'd rather just get this working.
Update: I've narrowed it down to the Restangular part - if instead of calling the Restangular upload function, I use $http, the callback is triggered as expected and all is good...so that's what I'm going to do, but if anyone can tell me what the problem was I'd be grateful.
Relevant code:
/** cameraService functions **/
//when the user chooses to snap a picture from the camera
takePicture: function(){
var options = {
quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
//when the user chooses to select image from the gallery
choosePicture: function(){
var options = {
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY
};
return $cordovaCamera.getPicture(options).then(
function(imageData) {
return imageData;
},
function(err) {
console.log("error", err);
});
},
uploadPicture: function(imageSource, caption, is_logo){
if (typeof is_logo == 'undefined') is_logo = false;
var upload_object = {
caption: caption,
source: imageSource,
is_logo: is_logo
};
//apiService is my wrapper for Restangular
return apiService.uploadFile(loadingService.getClientUrl('images'), upload_object);
},
/**apiService uploadFile - apparently the problem is here ***/
uploadFile: function(baseElem, object, route, path){
var headers = apiFunctions.setHeaders({'Content-Type': undefined});
//this DOES NOT WORK (on iPhone with image from camera) - request completes but callback not triggered
return Restangular.all(baseElem).customPOST(object, path, route, headers);
//this works fine:
return $http.post('https://api.mysite.dev/v1/clients/'+localStorageService.getValue('client_id')+'/images', JSON.stringify(object), {headers:headers}
);
},
/** controller functions **/
$scope.takePicture = function () {
cameraService.takePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.choosePicture = function () {
cameraService.choosePicture().then(function (imageData) {
$scope.data.imageSource = imageData;
});
};
$scope.uploadPicture = function () {
cameraService.uploadPicture($scope.data.imageSource, $scope.data.caption)
.then(function (response) { //this is never entered if image is captured from camera on iPhone
$ionicScrollDelegate.scrollTop();
$scope.data.caption = '';
$scope.data.imageSource = '';
if (response.data.response.is_success.data_value == true) {
$scope.messages.success.push("Photo uploaded successfully");
} else {
$scope.messages.failure.push("Error uploading photo.");
}
});
}
I'm using phonegap 3.3 and when I try to upload the upload the picture to server via file transfer plugin, I'm getting error 3 and http-status 500 on ios 7, on android it's working perfectly with no problem.
my client code:
function onSuccess(imageURI) {
$.mobile.loading('show');
try{
var options = new FileUploadOptions();
options.fileKey='file';
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType='image/jpeg';
var ft = new FileTransfer();
ft.upload(imageURI, path + "/Home/postPicture", win, fail, options);
} catch(err){
$.mobile.loading('hide');
alert(err);
}
}
function win(data) {
var obj = $.parseJSON(data.response);
$("#PictureSource").val(obj.PictureSource);
$.mobile.loading('hide');
}
function fail(error) {
$.mobile.loading('hide');
alert("error " + error.code);
}
function onFail() {
navigator.notification.alert(
'שגיאה לא ידועה...נסה שנית!', // message
alertDismissed, // callback
'שגיאה', // title
'אישור' // buttonName
);
}
function selectInput() {
navigator.notification.confirm(
'בחר את מקור התמונה', // message
onSelect, // callback to invoke
'בחירת מקור', // title
'מצלמה,גלריה, ביטול' // buttonLabels
);
}
function onSelect(input) {
switch(input)
{
case 1:
{
var destinationType = navigator.camera.DestinationType;
var sourceType = navigator.camera.PictureSourceType;
navigator.camera.getPicture(onSuccess, onFail, {
quality: 50,
destinationType: destinationType.FILE_URI,
//correctOrientation: true,
sourceType: sourceType.CAMERA
});
}
break;
case 2:
{
var destinationType = navigator.camera.DestinationType;
var sourceType = navigator.camera.PictureSourceType;
navigator.camera.getPicture(onSuccess, onFail, {
quality: 50,
destinationType: destinationType.FILE_URI,
sourceType: sourceType.PHOTOLIBRARY
});
}
break;
case 3:
alertDismissed();
break;
default:
alertDismissed();
}
}
function alertDismissed() {
// do nothing
}
and my server side in ASP.net MVC 4 is pretty much the same as here (I have chekced it, and it working with no problem on android).
Please help,
Update:
when I'm trying to upload image from gallery it does work on ios, but taking picture and uploading it doesn't work, do you thine is a phonegap/cordova bug? or it's something else?
I'm currently building an app for iOS using Phonegap/Cordova and jQuerymobile. The idea is to take photos with camera and store the captured image for future use. I would like to store the path/filename into my local database and to move the picture file to a persistent place in the iPhone.
Could someone provide me with an example ?
Ok, here is the solution.
in the Html file
I have an image tag for displaying the picture taken by the camera :
I have a button that runs a function for taking photo :
Capture Photo
The function to capture photo is (when the photo is taken, the scr of the 'smallImage' id is populated with the path of the photo)
function capturePhoto() {
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50 });
}
//Callback function when the picture has been successfully taken
function onPhotoDataSuccess(imageData) {
// Get image handle
var smallImage = document.getElementById('smallImage');
// Unhide image elements
smallImage.style.display = 'block';
smallImage.src = imageData;
}
//Callback function when the picture has not been successfully taken
function onFail(message) {
alert('Failed to load picture because: ' + message);
}
Now I want to move the picture in a permanent folder and then save the link into my database :
function movePic(file){
window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError);
}
//Callback function when the file system uri has been resolved
function resolveOnSuccess(entry){
var d = new Date();
var n = d.getTime();
//new file name
var newFileName = n + ".jpg";
var myFolderApp = "EasyPacking";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, successMove, resOnError);
},
resOnError);
},
resOnError);
}
//Callback function when the file has been moved successfully - inserting the complete path
function successMove(entry) {
//I do my insert with "entry.fullPath" as for the path
}
function resOnError(error) {
alert(error.code);
}
My file has been saved in the database to display it, i put "file://" front of the row that contains the image src
Hope this help.
J.
P.S. :
- many thanks to Simon Mac Donald (http://hi.im/simonmacdonald) for his post on googledocs.
Jerome's answer works like a charm.. the only thing to point out to people when they want to use the file don't use entry.fullPath as this can sometimes cause issues, use entry.toURL() as this will give you the full path without having to add "file://" to the path as well as bypassing issues such as SD card storage..
if (index == '0')
{
var options = {
quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false,
correctOrientation:true
};
$cordovaCamera.getPicture(options).then(movePic,function(imageData) {
$rootScope.imageUpload=imageData;
}, function(err) {
console.error(err);
});
function movePic(imageData){
console.log("move pic");
console.log(imageData);
window.resolveLocalFileSystemURL(imageData, resolveOnSuccess, resOnError);
}
function resolveOnSuccess(entry){
console.log("resolvetosuccess");
//new file name
var newFileName = itemID + ".jpg";
var myFolderApp = "ImgFolder";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
console.log("folder create");
//The folder is created if doesn't exist
fileSys.root.getDirectory( myFolderApp,
{create:true, exclusive: false},
function(directory) {
console.log("move to file..");
entry.moveTo(directory, newFileName, successMove, resOnError);
console.log("release");
},
resOnError);
},
resOnError);
}
function successMove(entry) {
//I do my insert with "entry.fullPath" as for the path
console.log("success");
//this is file path, customize your path
console.log(entry);
}
function resOnError(error) {
console.log("failed");
}
}
I just did a that works with promises, based on Jérôme's answer above:
function moveFile(file){
var deferred = $q.defer();
window.resolveLocalFileSystemURL(file,
function resolveOnSuccess(entry){
var dateTime = moment.utc(new Date).format('YYYYMMDD_HHmmss');
var newFileName = dateTime + ".jpg";
var newDirectory = "photos";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
//The folder is created if doesn't exist
fileSys.root.getDirectory( newDirectory,
{create:true, exclusive: false},
function(directory) {
entry.moveTo(directory, newFileName, function (entry) {
//Now we can use "entry.toURL()" for the img src
console.log(entry.toURL());
deferred.resolve(entry);
}, resOnError);
},
resOnError);
},
resOnError);
}, resOnError);
return deferred.promise;
}
function resOnError(error) {
console.log('Awwww shnap!: ' + error.code);
}
There are 3 steps:
Get the photo. Apple has a good example for this on the iPhone dev site
Get your Documents directory, like so:
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
And finally, storing the UIImage you got in step 1 out to disk:
NSString *filename = #"mypic.png";
NSString *fullpath = [docDir stringByAppendingPathComponent:filename];
[UIImagePNGRepresentation(image) writeToFile:fullpath atomically:YES];
I have been using the following code to grab a photo and display it in html works great.
function takePicture() {
navigator.camera.getPicture(
function(uri) {
var img = document.getElementById('camera_image1');
img.style.visibility = "visible";
img.style.display = "block";
img.src = uri;
document.getElementById('camera_status').innerHTML = "Success";
},
{ quality: 50, allowEdit: true, destinationType: navigator.camera.DestinationType.FILE_URI});
};
html later
<img style="width:144px;height:144px;" id="camera_image1" src="nophoto.jpg"/>
However I would like to save the image to the users Library at the same time, any pointer much appreciated.
I have tried using captureImage but this gives me less options like editing and did not place image inline in html.
Thanks again
PhoneGap 1.3
With Phonegap 2.2 you can save the image to the local device.
add "saveToPhotoAlbum : true" to the cameraOptions
function takePicture() {
navigator.camera.getPicture(
function(uri) {
var img = document.getElementById('camera_image1');
img.style.visibility = "visible";
img.style.display = "block";
img.src = uri;
document.getElementById('camera_status').innerHTML = "Success";
}, {
quality: 50,
allowEdit: true,
destinationType: navigator.camera.DestinationType.FILE_URI,
saveToPhotoAlbum : true
});
};
you'll have to change the phonegap code a bit. it wont save the image in the implementation thats there currently.
tell me if you are working on phonegap android. may be able to help u with that.