How to convert this image to json in angularjs? - angularjs

i take my picture with a camera after i want to post in the web service
so how to convert this image to format Json
my controller changed:
facebookExample.controller('MainCtrl', function($scope,$cordovaOauth, $localStorage, $location,$ionicPopup,$state,$http, Camera) {
$scope.fileArray = [];
$scope.imgContent = {};
$scope.imageStrings = [];
$scope.getPhoto = function(files) {
Camera.getPicture().then(function(imageURI) {
console.log(imageURI);
$scope.lastPhoto = imageURI;
angular.forEach(files, function(flowFile, i) {
var uri = imageURI;
$scope.imageStrings[i] = uri;
$scope.imgContent = {
fileName: flowFile.name,
fileContent: uri
};
fileReader.readAsDataURL(flowFile.file);
$scope.fileArray.push($scope.imgContent);
});
}, function(err) {
console.err(err);
}, {
quality: 75,
targetWidth: 320,
targetHeight: 320,
saveToPhotoAlbum: false
});
console.log("JSON.stringify($scope.fileArray)");
console.log(JSON.stringify($scope.fileArray));
};

You can try this code.
$scope.fileArray = [];
$scope.imgContent = {};
$scope.imageStrings = [];
$scope.processFiles = function(files) {
angular.forEach(files, function(flowFile, i) {
var fileReader = new FileReader();
fileReader.onload = function(event) {
var uri = event.target.result;
$scope.imageStrings[i] = uri;
$scope.imgContent = {
fileName: flowFile.name,
fileContent: uri
};
};
fileReader.readAsDataURL(flowFile.file);
$scope.fileArray.push($scope.imgContent);
});
console.log(JSON.stringify($scope.fileArray));
};
Or here is the jsfiddle

I tried this way and worked in one of my projects.Check it out.
Maybe it works for you too!
$cordovaCamera.getPicture(options).then(function(imagePath)
{
var promise = $service(imagePath);
promise.success(function(data)
{
//after service
});
}, function(error)
{
//An error occured
});
}
And here is an example service
$service=function(photo)
{
$http.defaults.headers.common["Accept"] = "application/json";
$http.defaults.headers.post["Content-Type"] = "application/json";
var data=JSON.stringify({photo:photo});
return $http.post("your webservice url",data);
};
Edit 1:Forgot to give you the camera options.Here you are!
var options = {
quality: 100,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
cameraDirection: Camera.Direction.FRONT,
correctOrientation: true,
saveToPhotoAlbum: true
};

Related

Ionic Photo Upload - File to Base64 String

I am working on an Ionic App that is communicating with a rails API. I have users, and user have pictures. I have been able to follow this guide about how to allow users to grab images natively from their phone images.
this allows the user to grab an image from their phone
$ionicPlatform.ready(function() {
$scope.getImageSaveContact = function() {
// Image picker will load images according to these settings
var options = {
maximumImagesCount: 1,
width: 800,
height: 800,
quality: 80
};
$cordovaImagePicker.getPictures(options).then(function (results) {
// Loop through acquired images
for (var i = 0; i < results.length; i++) {
$scope.collection.selectedImage = results[i]; // We loading only one image so we can use it like this
window.plugins.Base64.encodeFile($scope.collection.selectedImage, function(base64){ // Encode URI to Base64 needed for contacts plugin
$scope.collection.selectedImage = base64;
});
}
console.log("results");
console.log(results);
}, function(error) {
console.log('Error: ' + JSON.stringify(error));
});
};
});
The problem is, it is not running (or appears not to not be running) the window.plugins.Base64.encodeFile line that encodes a file. Right now, it is only the image file and not the Base64 encoded string.
How do I get this function to run, after I have grabbed a file from my device camera?
i was able to figure it out, answer is below
from an old project https://github.com/aaronksaunders/firebaseStorageApp/blob/master/www/js/app.js#L132
return $cordovaFile.readAsArrayBuffer(path, fileName)
.then(function (success) {
// success - get blob data
var imageBlob = new Blob([success], { type: "image/jpeg" });
})
add this camera plugin
cordova plugin add cordova-plugin-camera
this returns image in base 64 by default..
$scope.choosePhoto = function () {
$scope.myPopup.close();
var options = {
quality: 75,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 300,
targetHeight: 300,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false
};
$cordovaCamera.getPicture(options).then(function (imageData) {
$scope.imgURI = "data:image/jpeg;base64," + imageData;
}, function (err) {
// An error occured. Show a message to the user
});
}
more details can be found here
http://ngcordova.com/docs/plugins/camera/
hope this helps...
I was able to figure this out by piecing together a bunch of stuff, especially w/ the rails side. The idea is to click a button to get an image, pick one from your camera roll, convert that image to a base64 string, then send that image to the server.
my current stack is rails 4, ionic/angular v1. hopefully this helps someone else.
angular controller
function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
$scope.grabImage = function () {
var options = {
maximumImagesCount: 1,
width: 800,
height: 800,
quality: 80
};
$cordovaImagePicker.getPictures(options).then(function (results) {
$scope.dataImg = results;
return toDataUrl($scope.dataImg, function(base64Img) {
$scope.base64 = base64Img;
$state.go($state.current, {}, {reload: false});
})
}, function(error) {
$scope.message = "Error: Failed to Attach Image";
var alertPopup = $ionicPopup.alert({
title: 'User Photos',
templateUrl: 'templates/modals/success_or_error.html',
scope: $scope
});
});
}
rails controller
def create
image = Paperclip.io_adapters.for(params[:image_file])
image.class.class_eval { attr_accessor :original_filename, :content_type }
image.original_filename = "mu_#{#current_mobile_user.id}_#{#current_mobile_user.pictures.count}.jpg"
image.content_type = "image/jpeg"
#picture = #current_mobile_user.pictures.create(image: image, imageable_id: #current_mobile_user.id)
if #picture.save
render json: ['Picture Uploaded!'], status: :created
else
render json: [#picture.errors.full_messages.to_sentence], status: :unprocessable_entity
end
end

Processing multiple simultaneous uploads with Cordova

I want to upload 4 images from an ionic app to server side made using sails js.
An user can upload many images so before submit a form so I save all images in an array as its shown below
var cameraOptions = {
quality: 100,
destinationType: Camera.DestinationType.NATIVE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false,
allowEdit:true
};
var success = function(data){
$mdDialog.hide();
if(key==null)
{
compteurImage =compteurImage+1;
$scope.$apply(function () {
$scope.imgURI.push(data);
});
$scope.nombreImage=compteurImage;
}
else
{
$scope.$apply(function () {
$scope.imgURI[key]=data;
});
}
$rootScope.image=$scope.imgURI;
};
After having had all the images in an array, I loop on the array and I send each image to the server as shown below
for (var i = 0; i<$rootScope.image.length; i++) {
if (keepGoing) {
var options = new FileUploadOptions();
var params = {};
params.idArticle =response.article.idArticle;
var url=$rootScope.image[i].substr($rootScope.image[i].lastIndexOf('/') + 1);
options = {
fileKey: "file",
fileName:i+(url.split('?')[0]),
mimeType: "image/png",
idArticle: response.article.idArticle
};
options.params=params;
var failed = function (err) {
console.log(err);
keepGoing = false;
};
var success = function (result) {
count++;
if(count==$rootScope.image.length)
{
console.log("success");
}
};
var ft = new FileTransfer();
ft.upload($rootScope.image[i], Globals.urlServer + Globals.port + "/article/uploadImage", success, failed, options);
}
Server side the controller in charge of upload image is /article/uploadImage
uploadImage:function(req,res)
{
req.file('file')
.upload({ dirname: '../../assets/imagesArticle'},function (err, uploadedFiles) {
if (err) return res.serverError(err);
else {
var chemin = '';
var type = '';
uploadedFiles.forEach(function (file) {
chemin = require('path').basename(file.fd);
type = file.type;
Image.create({cheminImage:chemin, typeImage:type,article:req.body.idArticle}).exec(function(err,image){
if (err)
{
res.send({success:false});
}
if(image)
{
res.send({success:true});
}
})
});
}
});
},
My issue is if regardless how many pictures I upload, when I look image directory on server side, images are always identical and correspond to the last image of the images array. For example if I upload 3 differents images, on server side I get 3 identicals images whose correspond to the third or last image in array.
how can I fix it ?

Cordova/Ionic httpd server plugin - url not visible

i have a problem with Angular controller in my Ionic/Cordova project.
Can someone explain me why url which i get in line 25: $scope.serverURL=url;
isn't visible in line 63 alert($scope.serverURL); (it return null)?
Here is my controller:
var app = angular.module('iremotee');
app.controller('StreamingController', function(ConnectSdkService, $scope, $rootScope, $state, Camera) {
var options = {
quality: 100,
destinationType: 0,
sourceType: 0,
mediaType: 2
};
$scope.currentFile = null;
$scope.httpd = null;
$scope.serverURL = null;
alert($scope.serverURL + "!!!");
$scope.createHttpd = function() {
$scope.httpd = (cordova && cordova.plugins && cordova.plugins.CorHttpd) ? cordova.plugins.CorHttpd : null;
};
$scope.startMediaServer = function() {
if ($scope.httpd) {
// before start, check whether its up or not
$scope.httpd.getURL(function(url) {
if (url.length > 0) {
$scope.serverURL = url;
alert($scope.serverURL);
} else {
$scope.httpd.startServer({
'www_root': '/',
'port': 8080,
'localhost_only': false
}, function(url) {
$scope.serverURL = url;
alert($scope.serverURL);
}, function(error) {});
}
});
} else {}
};
$scope.stopServer = function() {
if ($scope.httpd) {
$scope.httpd.stopServer(function() {}, function(error) {});
}
};
$scope.getMedia = function() {
$state.go('mainmenu');
};
ionic.Platform.ready(function() {
$scope.createHttpd();
$scope.startMediaServer();
});
$scope.getFile = function() {
alert($scope.serverURL);
Camera.getFromMemory(options).then(function(URI) {
if (URI.indexOf("file://") == -1) {
URI = "file://" + URI;
}
window.resolveLocalFileSystemURL(URI, function(fileEntry) {
var URI = fileEntry.toURL();
var str = URI;
str = str.replace("file:///storage/emulated/0/", "/sdcard/");
str = str.replace("file:///storage/emulated/0/", "/sdcard1/");
str = str.replace("file:///storage", "");
Camera.currentURI = str;
alert(Camera.currentURI);
$scope.currentFile = Camera.currentURI;
}); //resolveLocalFileSystemURL-END
}, function(err) {
alert(err);
}); //getFromMemory-END
}; //getFile-END
$scope.$on('$destroy', function() {
$scope.stopServer();
});
});

Take in-app photo with Cordova Camera and upload it to Parse.com

I'm building an Ionic/Cordova app which uses Parse.com as a BaaS. It uses the ngCordova Camera plugin to control the device camera. The use-case is click a button, take a picture and have it upload to Parse. I've been researching the problem for a week now and still can't figure out why I can't get it to work.
The controller:
.controller('cameraCtrl', function($scope, camera) {
var cameraOptions = {
quality: 75,
destinationType: 0,
encodingType: 0,
targetWidth: 300,
targetHeight: 300,
mediaType: 0,
correctOrientation: true,
saveToPhotoAlbum: true
};
};
$scope.takePicture = function() {
cameraOptions.sourceType = 1;
navigator.camera.getPicture(onSuccess, onFail, cameraOptions);
}
$scope.selectPicture = function() {
cameraOptions.sourceType = 0;
navigator.camera.getPicture(onSuccess, onFail, cameraOptions);
}
function onSuccess(picture) {
File.upload(picture)
.success(function(data) {
// upload finish
});
$scope.$apply(function() {
$scope.preview = 'data:image/jpeg;base64,' + picture;
});
}
function onFail(resp) {
alert('Error: ' + resp);
}
});
The service:
angular.factory('File', function ($http) {
return {
upload: function (photo) {
var json = {
'base64': photo,
'_ContentType': 'image/jpeg'
}
var config = {
method: 'POST',
url: 'https://api.parse.com/1/files/pict.jpg',
data: json,
headers: {
'X-Parse-Application-Id': 'PCm0kDVeThvRcdFuS9lITrmskEhqjbqwFAydL2Lr',
'X-Parse-REST-API-Key': 'FhasGkTl0BLpJuLLJvPB2NFwlccXzVbirktdngXN'
}
};
return $http(config);
}
}
});
The HTML:
<button class="button" ng-click="takePicture()">
Any ideas as to why this doesn't work? Is there a better or more simple way to accomplish this? Any examples of this working somewhere? I've tried a dozen different solutions over the week and haven't found anything that works for my use-case. Thanks!
It would be helpful is you provided any error messages, but here is how I have solved the issue
var imageFile = new Parse.File("mypic.jpg", {base64: _params.photo});
console.log(imageFile);
// save the parse file
return imageFile.save().then(function () {
// create object to hold caption and file reference
var imageObject = new ImageObject();
// set object properties
imageObject.set("caption", _params.caption);
imageObject.set("picture", imageFile);
// save object to parse backend
return imageObject.save();
}, function (error) {
console.log("Error");
console.log(error);
});
There is a complete project here showing Parse.com integration with the File Object.
https://github.com/aaronksaunders/dcww/blob/master/www/js/services.js

Strange way to load the google map

I am using AngularJS + ionic and I am trying to create a google map. I am using the plugin cordova to get the exact position of the user and it works. In addition, the map is loaded only when the person takes a photo, there, is where obtendo such data. So there I have no problem, but the way the map is loaded strange, is clipped and navigation is pesima. I leave you my code and a picture of how the map looks.
<map center="{{latitud}}, {{longitud}}" zoom="15" style="width:100%;height:100%;" data-tap-disabled="true" id="mapa_view">
<marker position="{{latitud}}, {{longitud}}" />
</map>
.controller("CamaraCtrl", function($scope,$rootScope, Camera,$cordovaGeolocation) {
var posOptions = {timeout: 10000, enableHighAccuracy: false};
$cordovaGeolocation
.getCurrentPosition(posOptions)
.then(function (position) {
var latitud_actual = position.coords.latitude
var longitud_actual = position.coords.longitude
$scope.latitud = latitud_actual;
$scope.longitud = longitud_actual;
}, function(err) {
// error
});
$scope.mostrar_form = false;
$scope.getPhoto = function() {
Camera.getPicture().then(function(imageURI) {
console.log(imageURI);
$scope.lastPhoto = imageURI;
$scope.mostrar_form = true;
}, function(err) {
console.err(err);
}, {
quality: 75,
targetWidth: 320,
targetHeight: 320,
saveToPhotoAlbum: false
});
};
$scope.getPhoto();
})

Resources