Skip to main content

从文件系统加载照片

¥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

首先定义一个常量变量,该变量将充当 src/composables/usePhotoGallery.tsusePhotoGallery 函数顶部存储的键:

¥Begin by defining a constant variable that will act as the key for the store at the top of the usePhotoGallery function in src/composables/usePhotoGallery.ts:

const PHOTO_STORAGE = 'photos';

接下来,添加一个 cachePhotos 函数,将照片数组以 JSON 格式保存到首选项中:

¥Next, add a cachePhotos function that saves the Photos array as JSON to preferences:

const cachePhotos = () => {
Preferences.set({
key: PHOTO_STORAGE,
value: JSON.stringify(photos.value),
});
};

接下来,使用 Vue 监视功能 监视 photos 数组。每当数组被修改(在本例中为拍摄或删除照片)时,都会触发 cachePhotos 功能。我们不仅可以重用代码,而且应用用户关闭或切换到其他应用时也没关系 - 照片数据始终保存。

¥Next, use the Vue watch function to watch the photos array. Whenever the array is modified (in this case, taking or deleting photos), trigger the cachePhotos function. Not only do we get to reuse code, but it also doesn’t matter when the app user closes or switches to a different app - photo data is always saved.

watch(photos, cachePhotos);

现在照片数组数据已保存,创建一个函数以在 Tab2 加载时检索数据。首先,从 Preferences 中检索照片数据,然后将每张照片的数据转换为 Base64 格式:

¥Now that the photo array data is saved, create a function to retrieve the data when Tab2 loads. First, retrieve photo data from Preferences, then each photo's data into base64 format:

const loadSaved = async () => {
const photoList = await Preferences.get({ key: PHOTO_STORAGE });
const photosInPreferences = photoList.value ? JSON.parse(photoList.value) : [];

for (const photo of photosInPreferences) {
const file = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data,
});
photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
}

photos.value = photosInPreferences;
};

在移动设备上(接下来!),我们可以直接设置图片标签的来源 - <img src="x" /> - 文件系统上的每个照片文件,自动显示它们。然而,在网络上,我们必须将文件系统中的每个图片读取为 base64 格式,因为文件系统 API 在底层将它们存储在 IndexedDB 内的 base64 中。

¥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, because the Filesystem API stores them in base64 within IndexedDB under the hood.

最后,我们需要一种在加载照片库页面时调用 loadSaved 函数的方法。为此,请使用 Vue 挂载的生命周期钩子。早些时候我们已经从 Vue 导入了 onMounted

¥Finally, we need a way to call the loadSaved function when the Photo Gallery page is loaded. To do so, use the Vue mounted lifecycle hook. Earlier we had already imported onMounted from Vue:

import { ref, onMounted, watch } from 'vue';

usePhotoGallery 函数中,添加 onMounted 函数并调用 loadSaved

¥Within the usePhotoGallery function, add the onMounted function and call loadSaved:

onMounted(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!