从文件系统加载照片
¥Loading Photos from the Filesystem
我们已经实现了拍照并保存到文件系统。缺少最后一项功能:照片存储在文件系统中,但我们需要一种方法来保存每个文件的指针,以便它们可以在照片库中再次显示。
¥We’ve implemented photo taking and saving to the filesystem. There’s one last piece of functionality missing: the photos are stored in the filesystem, but we need a way to save pointers to each file so that they can be displayed again in the photo gallery.
幸运的是,这很容易:我们将利用 Capacitor 首选项 API 将照片数组存储在键值存储中。
¥Fortunately, this is easy: we’ll leverage the Capacitor Preferences API to store our array of Photos in a key-value store.
首选项 API
¥Preferences API
首先定义一个常量变量作为存储的键:
¥Begin by defining a constant variable that will act as the key for the store:
export class PhotoService {
public photos: UserPhoto[] = [];
private PHOTO_STORAGE: string = 'photos';
// other code
}
接下来,在 addNewToGallery
函数的末尾添加对 Preferences.set()
的调用以保存 Photos 数组。通过将其添加到此处,每次拍摄新照片时都会存储照片数组。这样,应用用户何时关闭或切换到其他应用并不重要 - 所有照片数据均已保存。
¥Next, at the end of the addNewToGallery
function, add a call to Preferences.set()
to save the Photos array. By adding it here, the Photos array is stored each time a new photo is taken. This way, it doesn’t matter when the app user closes or switches to a different app - all photo data is saved.
Preferences.set({
key: this.PHOTO_STORAGE,
value: JSON.stringify(this.photos),
});
保存照片数组数据后,创建一个名为 loadSaved()
的函数来检索该数据。我们使用相同的键来检索 JSON 格式的照片数组,然后将其解析为数组:
¥With the photo array data saved, create a function called loadSaved()
that can retrieve that data. We use the same key to retrieve the photos array in JSON format, then parse it into an array:
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[];
// more to come...
}
在移动设备上(接下来!),我们可以直接设置图片标签的来源 - <img src="x" />
- 文件系统上的每个照片文件,自动显示它们。然而,在网络上,我们必须使用 Photo
对象上的新 base64
属性,将文件系统中的每个图片读取为 base64 格式。这是因为文件系统 API 在底层使用了 IndexedDB。以下是你需要在刚刚添加的 loadSaved()
函数中添加的代码:
¥On mobile (coming up next!), we can directly set the source of an image tag - <img src="x" />
- to each photo file on the Filesystem, displaying them automatically. On the web, however, we must read each image from the Filesystem into base64 format, using a new base64
property on the Photo
object. This is because the Filesystem API uses IndexedDB under the hood. Below is the code you need to add in the loadSaved()
function you just added:
// 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}`;
}
之后,在 tab2.page.ts
中调用这个新方法,以便当用户第一次导航到选项卡 2(照片库)时,所有照片都会加载并显示在屏幕上。
¥After, call this new method in tab2.page.ts
so that when the user first navigates to Tab 2 (the Photo Gallery), all photos are loaded and displayed on the screen.
async ngOnInit() {
await this.photoService.loadSaved();
}
就是这样!我们在 Ionic 应用中构建了一个完整的照片库功能,可以在网络上运行。接下来,我们将把它转变成适用于 iOS 和 Android 的移动应用!
¥That’s it! We’ve built a complete Photo Gallery feature in our Ionic app that works on the web. Next up, we’ll transform it into a mobile app for iOS and Android!