ファイルシステムへの写真の保存
複数の写真を撮影し、アプリの 2 番目のタブにフォトギャラリーとして表示できるようになりました。ただし、これらの写真は現在永続的に保存されていないため、アプリを閉じると削除されます。
ファイルシステム API
幸いなことに、ファイルシステムに保存するには、いくつかの手順を実行するだけです。まず、`PhotoService` クラス (`src/app/services/photo.service.ts`) に新しいクラスメソッド `savePicture()` を作成します。新しくキャプチャされたデバイスの写真を表す `photo` オブジェクトを渡します。
private async savePicture(photo: Photo) { }
この新しいメソッドは、`addNewToGallery()` ですぐに使用できます。
public async addNewToGallery() {
// Take a photo
const capturedPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri, // file-based data; provides best performance
source: CameraSource.Camera, // automatically take a new photo with the camera
quality: 100 // highest quality (0 to 100)
});
// Save the picture and add it to photo collection
const savedImageFile = await this.savePicture(capturedPhoto);
this.photos.unshift(savedImageFile);
}
Capacitor の ファイルシステム API を使用して、写真をファイルシステムに保存します。最初に、写真を base64 形式に変換し、そのデータをファイルシステムの `writeFile` 関数に渡します。`tab2.page.html` で各画像のソースパス (`src` 属性) を `webviewPath` プロパティに設定することで、画面に各写真が表示されることを思い出してください。そのため、設定してから新しい `Photo` オブジェクトを返します。
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';
const savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: Directory.Data
});
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: photo.webPath
};
}
`readAsBase64()` は、次に定義するヘルパー関数です。プラットフォーム固有 (Web とモバイル) のロジックが少し必要になるため、別のメソッドで整理すると便利です。詳しくは後ほど説明します。ここでは、Web 上で実行するためのロジックを実装します。
private async readAsBase64(photo: Photo) {
// 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);
});
Web 上でカメラの写真を base64 形式で取得するのは、モバイルよりも少し難しいようです。実際には、組み込みの Web API を使用しているだけです。fetch() はファイルを blob 形式で読み込むための優れた方法であり、`FileReader` の readAsDataURL() は写真の blob を base64 に変換します。
これで完了です。新しい写真が撮影されるたびに、ファイルシステムに自動的に保存されるようになりました。