· 6 years ago · Jan 12, 2020, 02:18 PM
1import { Injectable } from '@angular/core';
2import { Plugins, CameraResultType, Capacitor, FilesystemDirectory, CameraPhoto, CameraSource, PhotosAlbumType } from '@capacitor/core';
3const { Camera, Filesystem, Storage } = Plugins;
4import { Platform } from '@ionic/angular';
5
6
7@Injectable({
8 providedIn: 'root'
9})
10export class PhotoService {
11
12 public photos: Photo[] = [];
13 private PHOTO_STORAGE: string = "photos";
14
15 constructor(private platform: Platform) {
16
17 }
18
19 public async addNewToGallery(){
20 try {
21 const capturedPhoto = await Camera.getPhoto({
22 resultType: CameraResultType.Uri,
23 source: CameraSource.Camera,
24 quality: 100
25 })
26 this.photos.unshift({
27 filepath: "soon...",
28 webviewPath: capturedPhoto.webPath
29 })
30
31 } catch (err) {
32 console.log("Camera issue:", err);
33 }
34
35 // "save" the photos array.
36 Storage.set({
37 key: this.PHOTO_STORAGE,
38 value: this.platform.is('hybrid')
39 ? JSON.stringify(this.photos)
40 : JSON.stringify(this.photos.map(p => {
41 const photoCopy = { ...p };
42 delete photoCopy.base64;
43
44 return photoCopy;
45 }))
46 })
47
48 }
49
50 public async loadSaved() {
51 // retrieve cached photo array data
52 const photos = await Storage.get({key: this.PHOTO_STORAGE});
53 this.photos = JSON.parse(photos.value) || [];
54
55 // Easiest way to detect when running on the web:
56 // "when the platform is NOT hybrid, do this"
57 if (!this.platform.is('hybrid')){
58 // Display the photo by reading into base64 format
59 for (let photo of this.photos) {
60 // Read each saved photo's data from the Filesystem
61 const readFile = await Filesystem.readFile({
62 path: photo.filepath,
63 directory: FilesystemDirectory.Data
64 });
65
66 // web platform only: save the photo into the base64 field
67 photo.base64 = `data:image/jpeg;base64,${readFile.data}`;
68 }}
69 }
70
71 private async savePicture(cameraPhoto: CameraPhoto){
72 // convert to base 64 format, for filesystem API
73 const base64Data = await this.readAsBase64(cameraPhoto);
74
75 // write the file to the data directory
76 const fileName = new Date().getTime() + ".jpeg";
77 await Filesystem.writeFile({
78 path: fileName,
79 data: base64Data,
80 directory: FilesystemDirectory.Data
81 });
82 // get the platform-specific photo filepaths
83 return await this.getPhotoFile(cameraPhoto, fileName);
84 }
85
86 private async readAsBase64(cameraPhoto: CameraPhoto){
87 // 'hybrid' will detect Cordova or Capacitor
88 if (this.platform.is('hybrid')) {
89 // Read the file into base64 format
90 const file = await Filesystem.readFile({
91 path: cameraPhoto.path
92 });
93 return file.data;
94 } else{
95
96 // Fetch the photo, read as a blob, then convert to base64 format
97
98 const response = await fetch(cameraPhoto.webPath!);
99 const blob = await response.blob();
100
101 return await this.convertBlobToBase64(blob) as string;
102 }
103 }
104
105 convertBlobToBase64 = (blob: Blob) => new Promise((resolve, reject) => {
106 const reader = new FileReader;
107 reader.onerror = reject;
108 reader.onload = () => {
109 resolve(reader.result);
110 };
111 reader.readAsDataURL(blob)
112 })
113
114 private async getPhotoFile(cameraPhoto, fileName) {
115
116 var fileUri;
117
118 if (this.platform.is('hybrid')){
119 // Get the new, complete filepath of the photo saved on filesystem
120 fileUri = await Filesystem.getUri({
121 directory: FilesystemDirectory.Data,
122 path: fileName
123 });
124
125
126 // Display the new image by rewriting the 'file://' path to HTTP
127 // Details: https://ionicframework.com/docs/building/webview#file-protocol
128 return {
129 filepath: fileUri.uir,
130 webviewPath: Capacitor.convertFileSrc(fileUri.uri)
131 }
132 } else {
133 // Use webPath to display the new image instead of base64 since it's
134 // already loaded into memory
135 return {
136 filepath: fileName,
137 webviewPath: cameraPhoto.webPath
138 };
139 }
140 }
141
142
143}
144
145interface Photo {
146 filepath: string;
147 webviewPath: string;
148 base64?: string;
149}