跳到主要内容
版本: v8

使用相机拍照

现在是乐趣所在的部分 - 使用 Capacitor 的 相机 API 添加使用设备相机拍照的能力。我们首先为网页构建它,然后进行一些小的调整使其在移动端(iOS 和 Android)上也能正常工作。

为此,我们将创建一个独立的组合函数,并与 Vue 的组合 API 配合使用,以管理图库中的照片。

注意

如果您不熟悉 Vue 的组合 API,Vue 官方文档的 为什么选择组合 API? 是一个很好的入门资源。

src/composables/usePhotoGallery.ts 中创建一个新文件并打开它。

我们将从导入将从 Vue 核心和 Capacitor 使用的各种实用程序开始。

import { ref, onMounted, watch } from 'vue';
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
import { Filesystem, Directory } from '@capacitor/filesystem';
import { Preferences } from '@capacitor/preferences';

接下来,创建一个名为 usePhotoGallery 的函数。

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

return {
takePhoto,
};
};

我们的 usePhotoGallery 函数公开了一个名为 takePhoto 的方法,该方法反过来调用 Capacitor 相机 API 的 getPhoto 方法。

请注意这里的巧妙之处:没有特定于平台的代码(网页、iOS 或 Android)!Capacitor 相机插件为我们抽象了这一切,只剩下一个方法调用 - getPhoto() - 它将打开设备的相机,并允许我们拍照。

我们需要采取的最后一步是从 Tab2 页面使用新函数。返回 Tab2Page.vue 并导入它。

import { usePhotoGallery } from '@/composables/usePhotoGallery';

usePhotoGallery 中解构 takePhoto 函数,以便我们可以在 template 中使用它。

<script setup lang="ts">
import {
IonContent,
IonCol,
IonFab,
IonFabButton,
IonGrid,
IonPage,
IonHeader,
IonIcon,
IonImg,
IonRow,
IonTitle,
IonToolbar,
} from '@ionic/vue';
import { camera, trash, close } from 'ionicons/icons';
import { usePhotoGallery } from '@/composables/usePhotoGallery';

const { takePhoto } = usePhotoGallery();
</script>

保存文件。如果尚未运行,请通过 ionic serve 启动开发服务器。在浏览器中,在“照片库”选项卡上,单击“相机”按钮。如果您的计算机有网络摄像头,将出现一个模式窗口。自拍!

A photo gallery app displaying a webcam selfie.

(您的自拍可能比我的好得多)

拍完照片后,它会立即消失。我们仍然需要在应用程序中显示它并保存它以便将来访问。

显示照片

首先,我们将创建一个新类型来定义我们的照片,它将包含特定的元数据。将以下 UserPhoto 接口添加到 usePhotoGallery.ts 文件中,位于主函数之外。

export interface UserPhoto {
filepath: string;
webviewPath?: string;
}

usePhotoGallery 函数的顶部,定义一个数组,以便我们可以存储使用相机拍摄的每张照片。使用 Vue 的 ref 函数 将其设为一个响应式变量。

const photos = ref<UserPhoto[]>([]);

当相机完成拍摄后,从 Capacitor 返回的 Photo 将被添加到 photos 数组中。更新 takePhoto 函数,在 Camera.getPhoto 行之后添加此代码。

const fileName = Date.now() + '.jpeg';
const savedFileImage = {
filepath: fileName,
webviewPath: photo.webPath,
};

photos.value = [savedFileImage, ...photos.value];

接下来,更新 return 语句以包含 photos 数组。

return {
photos,
takePhoto,
};

回到 Tab2 组件,更新导入语句以包含 UserPhoto 接口。

import { usePhotoGallery, UserPhoto } from '@/composables/usePhotoGallery';

然后,访问 photos 数组。

const { photos, takePhoto } = usePhotoGallery();

将照片存储到主数组后,我们现在可以将图像显示在屏幕上。添加一个 网格组件,以便每张照片在添加到图库时都能很好地显示,并循环遍历 Photos 数组中的每张照片,为每张照片添加一个图像组件(<ion-img>)。将 src(源)指向照片的路径。

<ion-content>
<ion-grid>
<ion-row>
<ion-col size="6" :key="photo.filepath" v-for="photo in photos">
<ion-img :src="photo.webviewPath"></ion-img>
</ion-col>
</ion-row>
</ion-grid>

<!-- <ion-fab> markup -->
</ion-content>

保存所有文件。在网页浏览器中,单击“相机”按钮并拍摄另一张照片。这次,照片将显示在“照片库”中!

接下来,我们将添加对将照片保存到文件系统支持,以便可以检索并显示在我们的应用程序中。