Skip to main content

将照片保存到文件系统

¥Saving Photos to the Filesystem

我们现在可以拍摄多张照片并将它们显示在应用第二个选项卡上的照片库中。然而,这些照片目前并未永久存储,因此当应用关闭时,它们将会丢失。

¥We’re now able to take multiple photos and display them in a photo gallery on the second tab of our app. These photos, however, are not currently being stored permanently, so when the app is closed, they will be lost.

文件系统 API

¥Filesystem API

幸运的是,将它们保存到文件系统只需几个步骤。首先打开 usePhotoGallery 钩子 (src/hooks/usePhotoGallery.ts),并从 Filesystem 类访问 writeFile 方法:

¥Fortunately, saving them to the filesystem only takes a few steps. Begin by opening the usePhotoGallery hook (src/hooks/usePhotoGallery.ts), and get access to the writeFile method from the Filesystem class:

注意

我们最初将使用 writeFile 方法,但很快我们将使用其他方法,因此我们现在将继续导入它们。

¥We will use the writeFile method initially, but we will use the others coming up shortly, so we'll go ahead and import them now.

接下来,在 usePhotoGallery 中创建几个新函数:

¥Next, create a couple of new functions in usePhotoGallery:

export function usePhotoGallery() {
const savePicture = async (photo: Photo, fileName: string): Promise<UserPhoto> => {
const base64Data = await base64FromPath(photo.webPath!);
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,
};
};
}

export async function base64FromPath(path: string): Promise<string> {
const response = await fetch(path);
const blob = await response.blob();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = reject;
reader.onload = () => {
if (typeof reader.result === 'string') {
resolve(reader.result);
} else {
reject('method did not return a string');
}
};
reader.readAsDataURL(blob);
});
}
注意

base64FromPath 方法是一个辅助实用程序,它从提供的路径下载文件并返回该文件的 Base64 表示形式。

¥The base64FromPath method is a helper util that downloads a file from the supplied path and returns a base64 representation of that file.

我们传入 photo 对象,它代表新捕获的设备照片,以及 fileName,它将提供文件的存储路径。

¥We pass in the photo object, which represents the newly captured device photo, as well as the fileName, which will provide a path for the file to be stored to.

接下来我们使用 Capacitor 文件系统 API 将照片保存到文件系统。我们首先将照片转换为 Base64 格式,然后将数据提供给文件系统的 writeFile 函数。

¥Next we use the Capacitor Filesystem API to save the photo to the filesystem. We start by converting the photo to base64 format, then feed the data to the Filesystem’s writeFile function.

最后,调用 savePicture 并在 takePhoto 方法中调用 setPhotos 的正下方传入照片对象和文件名。这是完整的方法:

¥Last, call savePicture and pass in the photo object and filename directly underneath the call to setPhotos in the takePhoto method. Here is the full method:

const takePhoto = async () => {
const photo = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100,
});

const fileName = Date.now() + '.jpeg';
const savedFileImage = await savePicture(photo, fileName);
const newPhotos = [savedFileImage, ...photos];
setPhotos(newPhotos);
};

我们开始吧!每次拍摄新照片时,它都会自动保存到文件系统中。

¥There we go! Each time a new photo is taken, it’s now automatically saved to the filesystem.