Old picture is not deleted when retaking a picture - javascript

When I take a picture everything works fine. The pic is made and I see it afterwards on the page. When I click to retake the pic I can do it, but now come the problem. The old picture is placed under the first picture Ive taken. I know that bc I can see a little bit of my 2. picture laying under my first picture. To see my second picture I have take a 3. picture (second time retake picture) Now the first pic is deleted, the 2. pic is on the top and the 3. is placed under the 2. pic. How can I achieve that the pic is directly deleted when I retake a picture?
export class PostPage {
public photos: any;
public base64Image: string;
constructor(public navCtrl: NavController, private camera: Camera) {
}
ngOnInit(){
this.photos = [];
}
ionViewDidEnter(){ //Damit Kamera automatisch öffent
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64:
this.base64Image = 'data:image/jpeg;base64,' + imageData;
this.photos.push(this.base64Image);
this.photos.reverse();
}, (err) => {
// Handle error
});
}
cancel(){
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64:
this.base64Image = 'data:image/jpeg;base64,' + imageData;
this.photos.push(this.base64Image);
this.photos.reverse();
}, (err) => {
// Handle error
});
}
}

Related

how to send pdf as a file as form-data to server

I have little knowledge on promises ,
What i have been doing is to convert html to pdf , thankfully html2pdf works great ,
Now where I was stuck is getting the pdf as a file and post to server with form-data
I have somehow found to get pdf encoded string from here
But it is a promise and i have a function as :
genPDF:function(){
var element = document.getElementById('canvasId');
var opt = {
filename: 'nobutton.pdf',
image: { type: 'jpeg', quality: 0.98 },
// html2canvas: { scale: 2 },
};
html2pdf().from(element).set(opt).toPdf().output('datauristring').then(function (res) {
var blobString = res;
console.log(blobString);
});
}
But here it doesn't log at first time , but then the function is called again and then logs , why is that ?? could i get it for the first time the function called ?
Can some one help me how to get the pdf from html2pdf as a file so that can append it to form-data , any help is really appreciated , Thanks :)
#Sophie - here is the asnyc version as discussed in the comments.
async genPDF() {
var element = document.getElementById('canvasId');
var opt = {
filename: 'nobutton.pdf',
image: { type: 'jpeg', quality: 0.98 },
// html2canvas: { scale: 2 },
};
let blobString = await html2pdf().from(element).set(opt).toPdf().output('datauristring');
console.log(blobString);
}

Ionic Capacitor cordova plugin unable to write image to library on Android

I am trying to use cordova-plugin-document-scanner with Ionic Capacitor for Android, but after the image is captured and when image crop UI should be displayed, it just returns to the capture screen again. This is the issue on the github repo. This is what seems relevant in the logcat console:
2020-08-03 13:26:05.320 27707-27707/si.test.app D/ViewRootImpl#9f2e8cd[ScanActivity]: Relayout returned: old=(0,0,1080,2280) new=(0,0,1080,2280) req=(1080,2280)4 dur=8 res=0x1 s={false 0} ch=false 2020-08-03 13:26:05.321 27707-27707/si.test.app D/ViewRootImpl#9f2e8cd[ScanActivity]: stopped(false) old=true 2020-08-03 13:26:05.328 27707-27707/si.test.app W/System.err: java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
2020-08-03 13:42:50.749 1278-1278/? E/Util: writeImageDataToRequestedUri : failed to make directory or the directory already existed.
2020-08-03 13:42:50.760 1278-1278/? E/Util: writeImageDataToRequestedUri : Returned because outputStream IOException.
This is my configuration:
Device: Samsung Galaxy S10e
OS: Android 10
#capacitor/core : 2.3.0
#capacitor/android: 2.3.0
cordova-plugin-document-scanner: 4.2.5
Is it possible, that Cordova and Capacitor have different paths to files on the device? Where could I fix that? Any help greatly appriciated :)
I implemented this in my project using Ionic 5 and Capacitor. It is long code. Try this and maybe help you.
Install this npms
npm install cordova-plugin-crop
npm install #ionic-native/crop
npm install cordova-plugin-ionic-webview
npm install #ionic-native/ionic-webview
Then create service file.
ex: photo.service
Then add below code according to your case. I added my full code to here because it include all things.
There are two method.
getImageCam() - get image from camera > source: CameraSource.Camera
getImageGall() - get image from gallery > source: CameraSource.Photos
import { Injectable } from "#angular/core";
import {
Plugins,
CameraResultType,
CameraPhoto,
CameraSource,
} from "#capacitor/core";
import { Crop } from "#ionic-native/crop/ngx";
import { WebView } from "#ionic-native/ionic-webview/ngx";
//import { File } from "#ionic-native/file/ngx";
const { Camera, Filesystem, Storage } = Plugins;
#Injectable({
providedIn: "root",
})
export class PhotoService {
newCapturedImg: any = null;
ImgNameStart: any = "yourName";
formDataImage: any;
cropImage: CameraPhoto;
constructor(private crop: Crop, private webview: WebView) {}
public async getImageCam() {
// Take a photo
const capturedPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100,
// allowEditing: true,
// height: 300,
// width: 300
});
console.log(capturedPhoto);
this.crop
.crop(capturedPhoto.path, {
quality: 100,
})
.then(
(newImage) => {
this.newCapturedImg = this.webview.convertFileSrc(newImage);
//console.log("new image path is: " + newImage);
//console.log("new image webpath is: " + this.newCapturedImg);
this.cropImage = {
path: newImage,
webPath: this.newCapturedImg,
format: "jpeg",
};
const savedImageFile = this.savePicture(this.cropImage);
},
(error) => console.error("Error cropping image", error)
);
}
public async getImageGall() {
// Take a photo
const capturedPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Photos,
quality: 100,
// allowEditing: true,
// height: 300,
// width: 300,
});
this.crop
.crop(capturedPhoto.path, {
quality: 100,
})
.then(
(newImage) => {
this.newCapturedImg = this.webview.convertFileSrc(newImage);
//console.log("new image path is: " + newImage);
//console.log(this.newCapturedImg);
this.cropImage = {
path: newImage,
webPath: this.newCapturedImg,
format: "jpeg",
};
const savedImageFile = this.savePicture(this.cropImage);
},
(error) => console.error("Error cropping image", error)
);
}
private async savePicture(cameraPhoto: CameraPhoto) {
const blobData = await this.readABlob(cameraPhoto);
this.formDataImage = blobData;
}
private async readABlob(cameraPhoto: CameraPhoto) {
const response = await fetch(cameraPhoto.webPath!);
const blob = await response.blob();
console.log("blob --> ", blob);
return blob;
}
createFileName() {
let d = new Date();
let n = d.getTime();
let newFileName = `${this.ImgNameStart + n}.jpg`;
return newFileName;
}
}
interface Photo {
filepath: string;
webviewPath: string;
base64?: string;
}
You can access service variable like this from any component.
example.page.ts
import { PhotoService } from "../../services/photo.service";
...
constructor(public photoService: PhotoService) {}
...
yourMethod() {
this.photoService.getImageCam() // or getImageGall()
let formDataImage = this.photoService.formDataImage;
let imageName = this.photoService.createFileName();
let urlToImageSrc = this.photoService.newCapturedImg;
}

Ionic - How to upload a base64 image to a Spring Boot endpoint which expects a MultipartFile?

I have an Spring Boot endpoint, which expects a MultipartFile, to upload a profile picture:
#RequestMapping(value="/picture", method=RequestMethod.POST)
public ResponseEntity<Void> uploadProfilePicture(#RequestParam(name="file") MultipartFile file) {
URI uri = service.uploadProfilePicture(file);
return ResponseEntity.created(uri).build();
}
It's working fine on Postman. Just to mention, I don't specify any Content-Type header, and I choose the file normally in the Body->form-data Postman section. Works perfectly!
But now I'm trying to request that endpoint through Ionic. First of all, I'm taking a picture using a similar code from official documentation, which stores the picture as base64:
getCameraPicture() {
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options)
.then(imageData => {
this.picture = 'data:image/jpeg;base64,' + imageData;
},
error => {
});
}
The above Ionic code is working fine: the picture taken is being stored in my picture variable and I could also see it in my screen using a <img [scr]="picture"> element.
Now I want to send that picture to my endpoint, but I'm not sure how to do that. The basic idea is to call an uploadPicture method from a service:
sendPicture() {
this.clientService.uploadPicture(this.picture)
.subscribe(response => {
...
},
error => {
...
});
}
And then implement that method in the service class:
uploadPicture(picture) {
let formData: FormData = new FormData();
formData.append('file', picture);
return this.http.post(
`${API_CONFIG.baseUrl}/clientes/picture`,
formData,
{
observe: 'response',
responseType: 'text'
}
);
}
I'm not sure if it's necessary to convert that base64 picture to blob or whatever. Anyway, I'm getting a MissingServletRequestPartException from my backend: "Required request part 'file' is not present".
So how to upload a base64 image to a Spring Boot endpoint which expects a MultipartFile?
You need to turn your base64 data to blob then you should send it.
dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var blob = new Blob([ab], {type: mimeString});
return blob;
}
reference

Angular JS Camera plugin base64 string

I am trying to use camera plugin with cordova app in ionic angular.js. My problem is that when i get picture it gives me a url of image not base64 string
I need base64 string.
in Services.js
.factory('Camera', function($q) {
return {
getPicture: function(options) {
var q = $q.defer();
navigator.camera.getPicture(function(result) {
q.resolve(result);
}, function(err) {
q.reject(err);
}, options);
return q.promise;
}
}
});
I user code above this returns
file:///storage/emulated/0/Android/data/com.example.app/cache/1313513121.jpg
but I want base64 string because I send it to server to save the image in server
in Controller.js
$scope.AddImage = function () {
var options = {
quality : 75,
targetWidth: 200,
targetHeight: 200,
sourceType: 1
};
Camera.getPicture(options).then(function(imageData) {
alert(imageData);
var item={
image: imageData
}
Pictures.push(item);
$scope.Photos = Pictures;
}, function(err) {
console.log(err);
});
}
I wrote code above. How can I solve this problem
Thanks in advance
Use the destinationType option parameter with value DATA_URL on the [ cameraOptions ].
navigator.camera.getPicture( cameraSuccess, cameraError, [
cameraOptions ] );
The option destinationType: Camera.DestinationType.DATA_URL will allow you to take a photo and retrieve the Base64-encoded image. Default this is set to destinationType: Camera.DestinationType.FILE_URI which will retrieve the image file location.
Below a general code sample which you can use to adapt your existing code.
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
}
function onFail(message) {
alert('Failed because: ' + message);
}
Documentation here

How would I get a File object from PhoneGap camera.getPicture?

This is probably simple and covered by some combination of functions in PhoneGap's "Camera" plugin, "File" plugin, or "File-Transfer" plugin. I understand the user can select a file with:
navigator.camera.getPicture(function (fileURI) {
// *** need help here ***
}, function ()
// handle errors
}, {
destinationType: window.Camera.DestinationType.FILE_URI,
sourceType: window.Camera.PictureSourceType.PHOTOLIBRARY,
mediaType: window.Camera.MediaType.ALLMEDIA
});
I can also change to destinationType: window.Camera.DestinationType.DATA_URL if that makes a difference.
My goal in the success handler is to get a File object (https://developer.mozilla.org/en-US/docs/Web/API/File).
Something like this should do it.
navigator.camera.getPicture(function (fileURI) {
window.resolveLocalFileSystemURL(fileURI,
function(fileEntry){
alert("got image file entry: " + fileEntry.fullPath);
// fileEntry.file() should return a raw HTML File Object
},
function(){//error}
);
}, function (){
// handle errors
}, {
destinationType: window.Camera.DestinationType.FILE_URI,
sourceType: window.Camera.PictureSourceType.PHOTOLIBRARY,
mediaType: window.Camera.MediaType.ALLMEDIA
});
window.resolveLocalFileSystemURI(fileURI, function(fileEntry) { /* your code here */ });

Categories