跳到主要内容
版本:v6

使用相机拍照

现在是有趣的部分——使用 Capacitor Camera API 添加使用设备相机拍照的功能。我们将从为 Web 构建开始,然后做一些小的调整使其在移动设备(iOS 和 Android)上工作。

为此,我们将创建一个独立的组合函数,与 Vue 的 Composition API 配合使用来管理相册的照片。

备注

如果你不熟悉 Vue 的 Composition API,官方 Vue 文档中的为什么使用 Composition 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 function usePhotoGallery() {
const takePhoto = async () => {
const photo = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100,
});
};

return {
takePhoto,
};
}

我们的 usePhotoGallery 函数暴露了一个名为 takePhoto 的方法,该方法又调用了 Capacitor Camera API 的 getPhoto 方法。

注意这里的奇妙之处:没有平台特定的代码(Web、iOS 或 Android)!Capacitor Camera 插件为我们抽象了这一点,只需要一个方法调用——getPhoto()——它将打开设备相机并允许我们拍照。

最后一步是从 Tab2 页面使用这个新函数。回到 Tab2.vue 并导入它:

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

接下来,在默认导出中,添加一个 setup 方法,作为 Composition API 的一部分。从 usePhotoGallery 中解构出 takePhoto 函数,然后返回它:

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

export default {
name: 'Tab2',
components: { IonPage, IonHeader, IonFab, IonFabButton, IonIcon,
IonToolbar, IonTitle, IonContent, IonGrid, IonRow,
IonCol, IonImg },
setup() {
const { takePhoto } = usePhotoGallery();

return {
takePhoto,
camera, trash, close
}
}
}
</script>

保存文件,如果你还没有运行开发服务器,请在浏览器中通过运行 ionic serve 重新启动。在相册标签上,点击相机按钮。如果你的计算机有任何类型的网络摄像头,会出现一个模态窗口。拍一张自拍!

一个相册应用显示网络摄像头自拍照。

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

拍照后,它立即消失了。我们还需要将其显示在我们的应用中并保存以供将来访问。

显示照片

首先,我们将创建一个新的类型来定义我们的 Photo,它将保存特定的元数据。在 usePhotoGallery.ts 文件中,在 main 函数之外的某处添加以下 UserPhoto 接口:

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

回到函数的顶部(在引用 Capacitor Camera 插件之后),定义一个数组以便我们可以存储每张用 Camera 拍摄的照片。使用 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 组件,更新 import 语句以包含 UserPhoto 接口:

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

然后,获取 photos 数组的访问权限:

const { photos, takePhoto } = usePhotoGallery();

最后,将 photos 添加到 setup() 的返回值中:

return {
photos,
takePhoto,
camera,
trash,
close,
};

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

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

<!-- <ion-fab> 标记 -->
</ion-content>

保存所有文件。在 Web 浏览器中,点击相机按钮再拍一张照片。这次,照片会显示在相册中!

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