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

カメラで写真を撮る

さあ、楽しい部分です。Capacitor Camera APIを使用して、デバイスのカメラで写真を撮る機能を追加しましょう。まずウェブ用に構築し、その後、モバイル(iOSとAndroid)で動作するように少し調整します。

これを行うために、ギャラリーの写真を管理する独自のカスタムReactフックを作成します。

注意

Reactフックに慣れていない場合は、公式ReactドキュメントのReactフックの紹介が、始めるための良いリソースです。

src/hooks/usePhotoGallery.tsに新しいファイルを作成して開きます。

カスタムフックは、他のReactフックを使用する関数にすぎません。それがこれから行うことです!Reactコア、Ionic React Hooksプロジェクト、およびCapacitorから使用するさまざまなフックとユーティリティをインポートすることから始めます。

import { useState, useEffect } from 'react';
import { isPlatform } from '@ionic/react';

import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
import { Filesystem, Directory } from '@capacitor/filesystem';
import { Preferences } from '@capacitor/preferences';
import { Capacitor } from '@capacitor/core';

次に、usePhotoGalleryという名前の関数を作成します。

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

return {
takePhoto,
};
}

usePhotoGalleryフックは、CapacitorのgetPhotoメソッドを呼び出すtakePhotoというメソッドを公開します。

ここでの魔法に注目してください。プラットフォーム固有のコード(ウェブ、iOS、またはAndroid)はありません!Capacitor Cameraプラグインはそれを抽象化して、デバイスのカメラを開いて写真を撮ることができるgetPhoto()という1つのメソッド呼び出しだけを残します。

最後に行う必要があるのは、Tab2ページから新しいフックを使用することです。Tab2.tsxに戻ってフックをインポートします。

import { usePhotoGallery } from '../hooks/usePhotoGallery';

そして、関数型コンポーネントのreturnステートメントの直前に、フックを使用してtakePhotoメソッドにアクセスします。

const Tab2: React.FC = () => {
const { takePhoto } = usePhotoGallery();

// snip - rest of code

ファイルを保存し、まだ行っていない場合は、ionic serveを実行してブラウザで開発サーバーを再起動します。「フォトギャラリー」タブで「カメラ」ボタンをクリックします。コンピュータに何らかのウェブカメラがある場合は、モーダルウィンドウが表示されます。自撮りをしてください!

A photo gallery app displaying a webcam selfie.

(あなたの自撮りの方がおそらく私よりもずっと良いでしょう)

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

写真の表示

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

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

関数の一番上(usePhotoGalleryの呼び出しの直後)に戻って、カメラでキャプチャした各写真の配列を格納するための状態変数を定義します。

const [photos, setPhotos] = useState<UserPhoto[]>([]);

カメラが写真撮影を完了すると、Capacitorから返された結果の写真はphoto変数に格納されます。新しい写真オブジェクトを作成し、それを写真の状態配列に追加します。新しい配列を作成して現在の写真配列を誤って変更しないようにし、setPhotosを呼び出して配列を状態に保存します。takePhotoメソッドを更新し、getPhoto呼び出しの後でこのコードを追加します。

const fileName = Date.now() + '.jpeg';
const newPhotos = [
{
filepath: fileName,
webviewPath: photo.webPath,
},
...photos,
];
setPhotos(newPhotos);

次に、フックから写真配列を公開しましょう。写真を含めるようにreturnステートメントを更新します。

return {
photos,
takePhoto,
};

そして、Tab2コンポーネントに戻って、写真にアクセスします。

const { photos, takePhoto } = usePhotoGallery();

メイン配列に保存された写真で、画面に画像を表示できます。Gridコンポーネントを追加して、写真がギャラリーに追加されるときに各写真がきちんと表示されるようにし、写真配列内の各写真をループして、各写真に画像コンポーネント(<IonImg>)を追加します。src(ソース)を写真のパスに指定します。

<IonContent>
<IonGrid>
<IonRow>
{photos.map((photo, index) => (
<IonCol size="6" key={photo.filepath}>
<IonImg src={photo.webviewPath} />
</IonCol>
))}
</IonRow>
</IonGrid>
<!-- <IonFab> markup -->
</IonContent>

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

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