Hello, everyone. I have been struggling for a few days with taking a photo with the phone camera and sending it to the server in a post request. I read a lot of posts with similar problems, but none of the solutions worked for me. I want to mention that I am quite new to the ionic world, so I am still learning. Maybe it is a stupid problem that I cannot see. This is my code:
constructor(private camera: Camera, private helperService: HelperService,
private httpClient: HttpClient, private DomSanitizer: DomSanitizer) {
}
image;
imageData;
ngOnInit() {
}
openCamera() {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
}
this.camera.getPicture(options).then((imageData) => {
this.imageData = imageData;
this.image = (<any>window).Ionic.WebView.convertFileSrc(imageData);
//extra http://localhost/file.. and I slice it to remove extra chars
this.image = this.image.slice(27);
},
(err) => {
this.helperService.showAlert(JSON.stringify(err));
});
}
upload() {
let url = 'url/to/post';
const date = new Date().valueOf();
const imageName = date + '.jpeg';
console.log(this.imageData); ---> undefined
//slice it to remove extra chars
this.imageData = this.imageData.slice(27);
const imageBlob = this.dataURItoBlob(this.imageData);
const imageFile = new File([imageBlob], imageName, { type: 'image/jpeg' });
let postData = new FormData();
postData.append('file', imageFile);
let data: Observable<any> = this.httpClient.post(url, postData);
data.subscribe((result) => {
this.helperService.showSuccess(result);
});
}
dataURItoBlob(dataURI) {
const byteString = window.atob(dataURI);
const arrayBuffer = new ArrayBuffer(byteString.length);
const int8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i++) {
int8Array[i] = byteString.charCodeAt(i);
}
const blob = new Blob([int8Array], { type: 'image/jpeg' });
return blob;
}
And here is the .html file where I want to display the picture. This step is quite optional because the thing that I want to accomplish is sendin the image to the backend. But, anyway I will add the html file:
<ion-content>
<ion-grid>
<img [src]="DomSanitizer.bypassSecurityTrustUrl(image)">
</ion-grid>
<ion-button (click)="upload()" color="success">
<ion-icon slot="icon-only" name="checkmark"></ion-icon>
</ion-button>
</ion-content>
This are my dependencies:
"dependencies": {
"@angular/common": "~8.2.14",
"@angular/core": "~8.2.14",
"@angular/forms": "~8.2.14",
"@angular/platform-browser": "~8.2.14",
"@angular/platform-browser-dynamic": "~8.2.14",
"@angular/router": "~8.2.14",
"@auth0/angular-jwt": "^4.0.0",
"@capacitor/cli": "^2.0.2",
"@capacitor/core": "^2.0.2",
"@ionic-native/base64": "^5.25.0",
"@ionic-native/camera": "^5.25.0",
"@ionic-native/core": "^5.0.7",
"@ionic-native/file": "^5.25.0",
"@ionic-native/file-path": "^5.25.0",
"@ionic-native/ionic-webview": "^5.25.0",
"@ionic-native/splash-screen": "^5.0.0",
"@ionic-native/status-bar": "^5.0.0",
"@ionic/angular": "^5.0.0",
"@ionic/pwa-elements": "^1.5.2",
"@ionic/storage": "^2.2.0",
"com-badrit-base64": "^0.2.0",
"cordova-android": "^8.1.0",
"cordova-browser": "^6.0.0",
"cordova-plugin-camera": "^4.1.0",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-filepath": "^1.5.8",
"cordova-plugin-ionic-webview": "^4.2.1",
"cordova-sqlite-storage": "^5.0.0",
"core-js": "^2.5.4",
"crypto-md5": "^1.0.0",
"rxjs": "~6.5.1",
"ts-md5": "^1.2.7",
"tslib": "^1.9.0",
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.803.20",
"@angular/cli": "~8.3.23",
"@angular/compiler": "~8.2.14",
"@angular/compiler-cli": "~8.2.14",
"@angular/language-service": "~8.2.14",
"@ionic/angular-toolkit": "^2.1.1",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "^5.0.0",
"cordova-plugin-device": "^2.0.2",
"cordova-plugin-ionic-keyboard": "^2.2.0",
"cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-statusbar": "^2.4.2",
"cordova-plugin-whitelist": "^1.3.3",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.4.3"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-sqlite-storage": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-camera": {},
"cordova-plugin-file": {},
"com-badrit-base64": {},
"cordova-plugin-filepath": {}
},
"platforms": [
"android",
"browser"
]
}
As a remark, I tried to display the photo with and without the dom optimizier and using different formats, but none worked. I am using Android 10.
Extra: Please do not take into consideration the fact that my code is quite ugly. I will divide the logic into a different service, but right now I wanted to try the code in a single file to see if I manage to make it work properly.
Problems:
First of all, the picture is not displayed on the screen.
Second of all, when I want to pass the picture to the post request, at the const imageBlob = this.dataURItoBlob(this.imageData); line, this.imageData is undefined.
Please help me, I do not know what to try anymore. Thanks!