メインコンテンツにスキップ
バージョン: v8

カメラで写真を撮る

いよいよ楽しいパートです。CapacitorのカメラAPIを使用して、デバイスのカメラで写真を撮る機能を追加します。まずはWeb向けにビルドし、次にモバイル(iOSとAndroid)で動作するように少し調整します。

そのため、ギャラリーの写真を管理するために、VueのComposition APIと組み合わせたスタンドアロンのコンポジション関数を作成します。

(省略:注意アイコンのSVG)注記

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 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`メソッドを呼び出します。

ここでの魔法に注目してください。プラットフォーム固有のコード(Web、iOS、またはAndroid)はありません! Capacitorカメラプラグインは、それを抽象化して、デバイスのカメラを開いて写真を撮ることができる1つのメソッド呼び出し( `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`を介して開発サーバーを起動します。ブラウザの[フォトギャラリー]タブで、[カメラ]ボタンをクリックします。コンピューターにWebカメラがある場合、モーダルウィンドウが表示されます。自撮り写真を撮ってください!

A photo gallery app displaying a webcam selfie.

(あなたの自撮りは、おそらく私のものよりはるかに優れているでしょう)

写真を撮った後、すぐに消えます。アプリ内に表示し、後でアクセスできるように保存する必要があります。

写真の表示

まず、特定のメタデータを保持するPhotoを定義する新しい型を作成します。次の`UserPhoto`インターフェースを、メイン関数のどこかにある`usePhotoGallery.ts`ファイルに追加します。

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

`usePhotoGallery`関数の先頭に、カメラでキャプチャした各写真を保存できる配列を定義します。 Vueのref関数を使用して、リアクティブ変数にします。

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

カメラが写真の撮影を完了すると、Capacitorから返された結果の`Photo`が`photos`配列に追加されます。 `Camera.getPhoto`行の後にこのコードを追加して、`takePhoto`関数を更新します。

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

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

次に、`photos`配列を含めるように`return`文を更新します。

return {
photos,
takePhoto,
};

Tab2コンポーネントに戻り、`UserPhoto`インターフェースを含めるように`import`文を更新します。

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>

すべてのファイルを保存します。 Webブラウザ内で、[カメラ]ボタンをクリックして別の写真を撮ります。今回は、写真がフォトギャラリーに表示されます!

次に、後で取得してアプリに表示できるように、写真をファイルシステムに保存するためのサポートを追加します。