-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphoto.service.ts
217 lines (175 loc) · 6.11 KB
/
photo.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import { Injectable } from '@angular/core';
// 19/8/24 DH:
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
import { Filesystem, Directory } from '@capacitor/filesystem';
import { Preferences } from '@capacitor/preferences';
import { Platform } from '@ionic/angular';
import { Capacitor } from '@capacitor/core';
// 7/10/24 DH:
import { AppscriptService } from './appscript.service';
// 27/10/24 DH:
import { Router, ActivatedRoute } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class PhotoService {
public photos: UserPhoto[] = [];
private PHOTO_STORAGE: string = 'photos';
private platform: Platform;
constructor(platform: Platform, public appscriptService: AppscriptService, private router: Router) {
this.platform = platform;
}
// 21/10/24 DH:
public async showPicture(photo: UserPhoto, position: number) {
//console.log("showPicture(): photo.filepath: ", photo.filepath);
//console.log("showPicture(): photo.webviewPath: ", photo.webviewPath);
// 27/10/24 DH: in shock that I've actually integrated 'photoviewer'...
// --------------------------------------------------------------------
// modes: 'one', 'gallery', 'slider'
this.router.navigateByUrl('/tabs/tab2/viewer/slider/' + position);
}
// 27/10/24 DH:
public getPicture(idx: number) {
return this.photos[idx];
}
// 19/8/24 DH: and we're back in Ionic/Angular land...:)
public async addNewToGallery() {
// Take a photo
// https://capacitorjs.com/docs/apis/camera#getphoto
const capturedPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100
});
/* Tutorial placeholder code
this.photos.unshift({
filepath: "soon...",
webviewPath: capturedPhoto.webPath!
});
*/
// Save the picture and add it to photo collection
const savedImageFile = await this.savePicture(capturedPhoto);
this.photos.unshift(savedImageFile);
console.log("savedImageFile.filepath: ", savedImageFile.filepath);
console.log("savedImageFile.webviewPath: ", savedImageFile.webviewPath);
Preferences.set({
key: this.PHOTO_STORAGE,
value: JSON.stringify(this.photos),
});
// 7/10/24 DH:
return capturedPhoto;
}
// 8/10/24 DH:
public async getPhoto() {
// Take a photo
const capturedPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100
});
return capturedPhoto;
}
// 8/10/24 DH:
public async savePhoto(photo: Photo) {
// Save the picture and add it to photo collection
const savedImageFile = await this.savePicture(photo);
this.photos.unshift(savedImageFile);
Preferences.set({
key: this.PHOTO_STORAGE,
value: JSON.stringify(this.photos),
});
}
public async loadSaved() {
// Retrieve cached photo array data
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
this.photos = (value ? JSON.parse(value) : []) as UserPhoto[];
// Easiest way to detect when running on the web:
// “when the platform is NOT hybrid, do this”
if (!this.platform.is('hybrid')) {
// Display the photo by reading into base64 format
for (let photo of this.photos) {
// Read each saved photo's data from the Filesystem
const readFile = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data
});
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
}
}
}
private async savePicture(photo: Photo) {
// Convert photo to base64 format, required by Filesystem API to save
const base64Data = await this.readAsBase64(photo);
// Write the file to the data directory
const fileName = Date.now() + '.jpeg';
// 1/10/24 DH: https://capacitorjs.com/docs/apis/filesystem#writefileoptions
const savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: Directory.Data
});
if (this.platform.is('hybrid')) {
// Display the new image by rewriting the 'file://' path to HTTP
// Details: https://ionicframework.com/docs/building/webview#file-protocol
return {
filepath: savedFile.uri,
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
};
}
else {
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: photo.webPath
};
}
}
private async readAsBase64(photo: Photo) {
// "hybrid" will detect Cordova or Capacitor
if (this.platform.is('hybrid')) {
// Read the file into base64 format
const file = await Filesystem.readFile({
path: photo.path!
});
return file.data;
}
else {
// Fetch the photo, read as a blob, then convert to base64 format
const response = await fetch(photo.webPath!);
const blob = await response.blob();
return await this.convertBlobToBase64(blob) as string;
}
}
private convertBlobToBase64 = (blob: Blob) => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = reject;
reader.onload = () => {
resolve(reader.result);
};
reader.readAsDataURL(blob);
});
// 21/8/24 DH:
public async deletePicture(photo: UserPhoto, position: number) {
// Remove this photo from the Photos reference data array
this.photos.splice(position, 1);
// Update photos array cache by overwriting the existing photo array
Preferences.set({
key: this.PHOTO_STORAGE,
value: JSON.stringify(this.photos)
});
// delete photo file from filesystem
const filename = photo.filepath
.substr(photo.filepath.lastIndexOf('/') + 1);
await Filesystem.deleteFile({
path: filename,
directory: Directory.Data
});
}
}
// 19/8/24 DH:
export interface UserPhoto {
filepath: string;
webviewPath?: string;
}