Run in terminal
`
ionic start devdacticImages blank –type=angular
cd devdacticImages
npm i @ionic-native/camera@beta
npm i @ionic-native/file@beta
npm i @ionic-native/ionic-webview@beta
npm i @ionic-native/file-path@beta
ionic cordova plugin add cordova-plugin-camera
ionic cordova plugin add cordova-plugin-file
ionic cordova plugin add cordova-plugin-ionic-webview
ionic cordova plugin add cordova-sqlite-storage
ionic cordova plugin add cordova-plugin-filepath
`
Change src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, RouteReuseStrategy, Routes } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { Camera } from '@ionic-native/Camera/ngx';
import { File } from '@ionic-native/File/ngx';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { FilePath } from '@ionic-native/file-path/ngx';
import { IonicStorageModule } from '@ionic/storage';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule,
HttpClientModule,
IonicStorageModule.forRoot()
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
Camera,
File,
WebView,
FilePath
],
bootstrap: [AppComponent]
})
export class AppModule {}
Change src/app/home/home.page.html
<ion-header>
<ion-toolbar color="primary">
<ion-title>
Ionic Image Upload
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<h3 *ngIf="images.length == 0" text-center>Please Select Image!</h3>
<ion-list>
<ion-item *ngFor="let img of images; index as pos" text-wrap>
<ion-thumbnail slot="start">
<ion-img [src]="img.path"></ion-img>
</ion-thumbnail>
<ion-label>
{{ img.name }}
</ion-label>
<ion-button slot="end" fill="clear" (click)="startUpload(img)">
<ion-icon slot="icon-only" name="cloud-upload"></ion-icon>
</ion-button>
<ion-button slot="end" fill="clear" (click)="deleteImage(img, pos)">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-button>
</ion-item>
</ion-list>
</ion-content>
<ion-footer>
<ion-toolbar color="primary">
<ion-button fill="clear" expand="full" color="light" (click)="selectImage()">
<ion-icon slot="start" name="camera"></ion-icon>
Select Image</ion-button>
</ion-toolbar>
</ion-footer>
Change src/app/home/home.page.ts
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { Camera, CameraOptions, PictureSourceType } from '@ionic-native/Camera/ngx';
import { ActionSheetController, ToastController, Platform, LoadingController } from '@ionic/angular';
import { File, FileEntry } from '@ionic-native/File/ngx';
import { HttpClient } from '@angular/common/http';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { Storage } from '@ionic/storage';
import { FilePath } from '@ionic-native/file-path/ngx';
import { finalize } from 'rxjs/operators';
const STORAGE_KEY = 'my_images';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
images = [];
constructor(private camera: Camera, private file: File, private http: HttpClient, private webview: WebView,
private actionSheetController: ActionSheetController, private toastController: ToastController,
private storage: Storage, private plt: Platform, private loadingController: LoadingController,
private ref: ChangeDetectorRef, private filePath: FilePath) { }
ngOnInit() {
this.plt.ready().then(() => {
this.loadStoredImages();
});
}
loadStoredImages() {
this.storage.get(STORAGE_KEY).then(images => {
if (images) {
let arr = JSON.parse(images);
this.images = [];
for (let img of arr) {
let filePath = this.file.dataDirectory + img;
let resPath = this.pathForImage(filePath);
this.images.push({ name: img, path: resPath, filePath: filePath });
}
}
});
}
pathForImage(img) {
if (img === null) {
return '';
} else {
let converted = this.webview.convertFileSrc(img);
return converted;
}
}
async presentToast(text) {
const toast = await this.toastController.create({
message: text,
position: 'bottom',
duration: 3000
});
toast.present();
}
async selectImage() {
const actionSheet = await this.actionSheetController.create({
header: "Select Image source",
buttons: [{
text: 'Load from Library',
handler: () = & gt; {
this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
handler: () = & gt; {
this.takePicture(this.camera.PictureSourceType.CAMERA);
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
await actionSheet.present();
}
takePicture(sourceType: PictureSourceType) {
var options: CameraOptions = {
quality: 100,
sourceType: sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
this.camera.getPicture(options).then(imagePath => {
if (this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath)
.then(filePath => {
let correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
let currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
});
} else {
var currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
var correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}
});
createFileName() {
var d = new Date(),
n = d.getTime(),
newFileName = n + ".jpg";
return newFileName;
}
copyFileToLocalDir(namePath, currentName, newFileName) {
this.file.copyFile(namePath, currentName, this.file.dataDirectory, newFileName).then(success => {
this.updateStoredImages(newFileName);
}, error => {
this.presentToast('Error while storing file.');
});
}
updateStoredImages(name) {
this.storage.get(STORAGE_KEY).then(images => {
let arr = JSON.parse(images);
if (!arr) {
let newImages = [name];
this.storage.set(STORAGE_KEY, JSON.stringify(newImages));
} else {
arr.push(name);
this.storage.set(STORAGE_KEY, JSON.stringify(arr));
}
let filePath = this.file.dataDirectory + name;
let resPath = this.pathForImage(filePath);
let newEntry = {
name: name,
path: resPath,
filePath: filePath
};
this.images = [newEntry, ...this.images];
this.ref.detectChanges(); // trigger change detection cycle
});
deleteImage(imgEntry, position) {
this.images.splice(position, 1);
this.storage.get(STORAGE_KEY).then(images => {
let arr = JSON.parse(images);
let filtered = arr.filter(name => name != imgEntry.name);
this.storage.set(STORAGE_KEY, JSON.stringify(filtered));
var correctPath = imgEntry.filePath.substr(0, imgEntry.filePath.lastIndexOf('/') + 1);
this.file.removeFile(correctPath, imgEntry.name).then(res => {
this.presentToast('File removed.');
});
});
// Inspired by https://golb.hplar.ch/2017/02/Uploading-pictures-from-Ionic-2-to-Spring-Boot.html
startUpload(imgEntry) {
this.file.resolveLocalFilesystemUrl(imgEntry.filePath)
.then(entry => {
( < FileEntry > entry).file(file => this.readFile(file))
})
.catch(err => {
this.presentToast('Error while reading file.');
});
}
readFile(file: any) {
const reader = new FileReader();
reader.onloadend = () => {
const formData = new FormData();
const imgBlob = new Blob([reader.result], {
type: file.type
});
formData.append('file', imgBlob, file.name);
this.uploadImageData(formData);
};
reader.readAsArrayBuffer(file);
}
async uploadImageData(formData: FormData) {
const loading = await this.loadingController.create({
content: 'Uploading image...',
});
await loading.present();
this.http.post("http://localhost:8888/upload.php", formData)
.pipe(
finalize(() => {
loading.dismiss();
})
)
.subscribe(res => {
if (res['success']) {
this.presentToast('File upload complete.')
} else {
this.presentToast('File upload failed.')
}
});
}