I am working with ionic 3 framework.and i don't know how to convert base64 image to blob Thank you.
.ts file
openCamera() {
let actionSheet = this.actionSheetCtrl.create({
title: 'Edit Your Profile Picture',
buttons: [
{
text:'Camera',
icon: 'ios-camera',
role: 'destructive',
handler: () => {
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
saveToPhotoAlbum: true,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
this.image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
alert(err)
});
}
},
{
text: 'Gallery',
icon: 'ios-images',
handler: () => {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType:this.camera.PictureSourceType.PHOTOLIBRARY,
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64 (DATA_URL):
this.image = 'data:image/jpeg;base64,' + imageData;
//this.image = base64Image;
// alert(base64Image);
}, (err) => {
// Handle error
console.log(err);
});
}
},
{
text: 'Cancel',
role: 'cancel',
handler: () => {
}
}
]
});
actionSheet.present();
}
.html file
<img (click)="openCamera()" [src]="domSanitizer.bypassSecurityTrustUrl(image)" class="before-img" >
Default setting is the file URI (blob) according to this:
https://ionicframework.com/docs/native/camera/#CameraOptions
So you can alter your current options here to request FILE URI instead of DATA URL (as your current options set to use DATA URL which is base64):
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType:this.camera.PictureSourceType.PHOTOLIBRARY,
}
You can also omit setting this explicitly and then in theory the default will be used...
Related
Nothing happens when I call the getPicture function with: this.camera.PictureSourceType.PHOTOLIBRARY.
Hower it does work in Android just not iOs and also this.camera.PictureSourceType.CAMERA does work in iOs.
private cameraOptions: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
};
public async changeProfilePicture() {
const sheet = await this.actionSheet.create({
buttons: [{
text: 'Camera',
handler: () => {
this.takePicture();
},
},
{
text: 'Foto album',
handler: () => {
this.choosePicture();
},
}
, {
text: 'Annuleren',
role: 'cancel',
handler: () => {
sheet.dismiss();
},
}],
});
sheet.present();
}
private async takePicture() {
try {
const image = await this.camera.getPicture({
...this.cameraOptions,
sourceType: this.camera.PictureSourceType.CAMERA,
});
this.userService.editProfilePicture(`data:image/jpeg;base64,${image}`).subscribe(user => {
this.user = user;
});
} catch (err) {
this.handleImageError(err);
}
}
private async choosePicture() {
try {
const image = await this.camera.getPicture({
...this.cameraOptions,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
});
this.userService.editProfilePicture(`data:image/jpeg;base64,${image}`).subscribe(user => {
this.user = user;
});
} catch (err) {
this.handleImageError(err);
}
}
iOS requires permissions to be configured when accessing certain native features. In your case, you need to set the NSPhotoLibraryUsageDescription key in the Info.plist file of your app. You can manually edit this file within the xcode project, but it's better to place this in the config.xml of your ionic project :
<config-file parent="NSPhotoLibraryUsageDescription" platform="ios" target="*-Info.plist">
<string>The app needs access to your library to...</string>
</config-file>
I am working on my Ionic 4 app and I have used the camera plugin for image uploading and I have converted the image to the base64 for showing the image but the problem is that I am not able to convert the base64 to proper image path for sending it to the API.
This is my editimage.page.html:
<ion-item class="newitem2">
<ion-avatar class="image-center">
<img name="profile_pic" [src]="this.userdetailsedit.value.profile_pic"/>
<ion-icon (click)="presentActionSheet()" class="myicon11" name="create"></ion-icon>
</ion-avatar>
</ion-item>
This is my editprofile.page.ts:
async UpdateUserDetails(){
this.storage.get('USER').then(userde => {
if (userde) {
this.userdetails = userde;
const userdetailseditss = {
first_name: this.userdetailsedit.value.first_name,
last_name: this.userdetailsedit.value.last_name,
mobile: this.userdetailsedit.value.mobile,
profile_pic: this.userdetailsedit.value.profile_pic,
};
this.chakapi.UserProfileUpdate(userdetailseditss, 'userUpdateProfile/' + this.userdetails.id).subscribe((data) => {
console.log(data);
}, error => {
console.log(error); });
}
});
}
async imageuserchoose(sourceType){
const options: CameraOptions = {
quality: 76,
sourceType: sourceType,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum: true,
correctOrientation: true,
}
this.camera.getPicture(options).then((imageData) => {
if (sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
let path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
let filename = imageData.substring(imageData.lastIndexOf('/') + 1);
let index = filename.indexOf('?');
if (index > -1) {
filename = filename.substring(0,index);
}
this.file.readAsDataURL(path, filename).then(data => {
this.imagepic = data;
this.userdetailsedit.patchValue({
profile_pic: data,
});
});
}
if (sourceType === this.camera.PictureSourceType.CAMERA) {
let filename = imageData.substring(imageData.lastIndexOf('/') + 1);
let path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
this.file.readAsDataURL(path, filename).then(data => {
this.imagepic = data;
this.userdetailsedit.patchValue({
profile_pic: data,
});
});
}
}, (err) => {
});
}
async presentActionSheet() {
const actionSheet = await this.actionSheetController.create({
header: 'Select Image Source',
backdropDismiss:true,
buttons: [{
text: 'Choose From Gallery',
icon: 'images',
cssClass: 'myActionSheetBtnStyle',
handler: () => {
this.imageuserchoose(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
icon: 'camera',
cssClass: 'myActionSheetBtnStyle',
handler: () => {
this.imageuserchoose(this.camera.PictureSourceType.CAMERA);
}
}]
});
await actionSheet.present();
}
}
The problem is that when I am sending the image to the API, it is base64 and I am not able to convert it before sending.
Any help is much appreciated.
Please try this. You can use file transfer Native Plugin for this. It will solve your problem.
In the ts file:
async UpdateUserDetails(){
if(this.imagepic && this.fileUploadName) {
let fileTransfer = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'profile_pic',
fileName: this.fileUploadName,
headers: {}
}
options.params = {
first_name: this.userdetailsedit.value.first_name,
last_name: this.userdetailsedit.value.last_name,
mobile: this.userdetailsedit.value.mobile,
old_password: this.userdetailsedit.value.old_password,
password: this.userdetailsedit.value.password,
};
this.storage.get('USER').then(userde => {
if (userde) {
this.userdetails = userde;
fileTransfer.upload(this.imagepic, this.apiUrl+'userUpdateProfile/'+this.userdetails.id, options)
.then((data) => {
if(data && data.responseCode==200){
let response=JSON.parse(data.response);
if(response.status === "success"){
this.storage.set('ID', response.data.id);
this.storage.set('USER', response.data);
this.modalController.dismiss();
} else{
loading2.dismiss();
}
}else{
//show error msg
}
}, (err) => {
console.log('upload err ::',err);
});
}
});
}
}
async imageuserchoose(sourceType){
const options: CameraOptions = {
quality: 76,
sourceType: sourceType,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum: true,
correctOrientation: true,
// allowEdit: true,
}
this.camera.getPicture(options).then((imageData) => {
let filename,path;
this.imagepic = imageData;
if (sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
filename = imageData.substring(imageData.lastIndexOf('/') + 1);
let index = filename.indexOf('?');
if (index > -1) {
filename = filename.substring(0,index);
}
}
if (sourceType === this.camera.PictureSourceType.CAMERA) {
filename = imageData.substring(imageData.lastIndexOf('/') + 1);
path = imageData.substring(0, imageData.lastIndexOf('/') + 1);
console.log(path,'FileName::', filename);
}
this.fileUploadName=filename;
this.file.readAsDataURL(path, filename).then(data => {
this.userdetailsedit.patchValue({
profile_pic: data,
});
});
}, (err) => {
// Handle error
});
}
This will solve your problem.
[enter image description here][1]I was using facing issue while open camera using action sheet and getting following error.
CameraProxy.js:105 Uncaught TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.
at successCallback (CameraProxy.js:105)
My ionic camera version is "#ionic-native/camera": "^4.3.0".
Is there an issue with actionsheet or native plugin?
My camera is getting started but not working.
The below was typescript code for camera
const actionSheet = this.actionSheetController.create({
title: 'Actions',
buttons: [{
text: 'upload',
role: 'destructive',
icon: 'upload',
handler: () => {
console.log('camera clicked');
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
};
this.camera.getPicture(options).then((imageData) => {
this.ProfileInfo.profileImagePath = 'data:image/png;base64,' + imageData;
this.ProfileInfo.profileimage = imageData;
this.updateImage(this.ProfileInfo);
}, (err) => {
});
}
}, {
text: 'camera',
icon: 'camera',
handler: () => {
console.log('camera clicked');
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.CAMERA
};
this.camera.getPicture(options).then((imageData) => {
this.ProfileInfo.profileImagePath = 'data:image/png;base64,' + imageData;
this.ProfileInfo.profileimage = imageData;
this.updateImage(this.ProfileInfo);
}, (err) => {
});
}
}, {
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}]
});
actionSheet.present();
I tried testing my ionic image upload app in browser but since I can not upload image due to cordova_not_available been displayed on the screen, every time I click ed on the upload button this error pop up Cannot read property 'split' of undefined
**
NewpostPage.html:51 ERROR ReferenceError: FileTransfer is not defined at new Transfer (VM1294 vendor.js:149642) at NewpostPage.webpackJsonp.162.NewpostPage.uploadPhoto (VM1295 main.js:601) at Object.eval [as handleEvent] (VM1527 NewpostPage.ngfactory.js:180) at handleEvent (VM1294 vendor.js:13963) at callWithDebugContext (VM1294 vendor.js:15472) at Object.debugHandleEvent [as handleEvent] (VM1294 vendor.js:15059) at dispatchEvent (VM1294 vendor.js:10378) at VM1294 vendor.js:11003 at HTMLButtonElement. (VM1294 vendor.js:39326) at t.invokeTask (VM1427 polyfills.js:3)
**
in my upload.ts i have this
uploadPhoto() {
let loader = this.loadingCtrl.create({
content: "Please wait..."
});
loader.present();
//let filename = this.imagePath.split('/').pop();
console.log('this.imagePath: ', this.imagePath)
let filename = this.imagePath;
let options = {
fileKey: "file",
fileName: filename,
chunkedMode: false,
mimeType: "image/jpg",
params: {'location': this.location, 'title': this.postTitle, 'description': this.desc }
};
const fileTransfer = new Transfer();
fileTransfer.upload(this.imageNewPath, AppSettings.API_UPLOAD_ENDPOINT,
options).then((entry) => {
this.imagePath = '';
this.imageChosen = 0;
loader.dismiss();
this.navCtrl.setRoot(IncidentsPage);
}, (err) => {
alert(JSON.stringify(err));
});
}
chooseImage() {
let actionSheet = this.actionSheet.create({
title: 'Choose Picture Source',
buttons: [
{
text: 'Gallery',
icon: 'albums',
handler: () => {
this.actionHandler(1);
}
},
{
text: 'Camera',
icon: 'camera',
handler: () => {
this.actionHandler(2);
}
},
{
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}
]
});
actionSheet.present();
}
//}
actionHandler(selection: any) {
var options: any;
if (selection == 1) {
options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
saveToPhotoAlbum: false
};
} else {
options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
saveToPhotoAlbum: false
};
}
Camera.getPicture(options).then((imgUrl) => {
var sourceDirectory = imgUrl.substring(0, imgUrl.lastIndexOf('/') + 1);
var sourceFileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1, imgUrl.length);
sourceFileName = sourceFileName.split('?').shift();
File.copyFile(sourceDirectory, sourceFileName, cordova.file.externalApplicationStorageDirectory, sourceFileName).then((result: any) => {
this.imagePath = imgUrl;
this.imageChosen = 1;
this.imageNewPath = result.nativeURL;
}, (err) => {
alert(JSON.stringify(err));
})
}, (err) => {
alert(JSON.stringify(err))
});
}
Please help out.
I think i see what you are asking now.
You need to check for undefined and "" before running the code inside uploadPhoto().
uploadPhoto() {
if(this.imagePath !== undefined || this.imagePath !== '') {
let loader = this.loadingCtrl.create({
content: "Please wait..."
});
loader.present();
//let filename = this.imagePath.split('/').pop();
console.log('this.imagePath: ', this.imagePath)
let filename = this.imagePath;
let options = {
fileKey: "file",
fileName: filename,
chunkedMode: false,
mimeType: "image/jpg",
params: {'location': this.location, 'title': this.postTitle, 'description': this.desc }
};
const fileTransfer = new Transfer();
fileTransfer.upload(this.imageNewPath, AppSettings.API_UPLOAD_ENDPOINT,
options).then((entry) => {
this.imagePath = '';
this.imageChosen = 0;
loader.dismiss();
this.navCtrl.setRoot(IncidentsPage);
}, (err) => {
alert(JSON.stringify(err));
});
}
} else {
//do something else
}
I use the native plugin http://ionicframework.com/docs/native/camera/ to access the Camera or Photo Gallery.
I need a solution to access the camera and switch to the photo gallery if necessary.
Is there such a plug-in or not?
As Swapnil Patwa says in the comment, you can ask the user with an ActionSheet:
public showActionSheet() {
let actionSheet = this.actionSheetCtrl.create({
buttons: [{
text: 'Load from gallery',
handler: () => {this.loadImage(this.camera.PictureSourceType.PHOTOLIBRARY);}
},{
text: 'Take a photo',
handler: () => {this.loadImage(this.camera.PictureSourceType.CAMERA);}
},{
text: 'Cancel',
role: 'cancel'
}]
});
actionSheet.present();
}
private loadImage(selectedSourceType:number){
let cameraOptions: CameraOptions = {
sourceType: selectedSourceType,
destinationType: this.camera.DestinationType.DATA_URL,
quality: 100,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
}
this.camera.getPicture(cameraOptions).then((imageData) => {
if(imageData!=null){
// Do with the image data what you want.
}
});
}