跳至主要內容
版本:v8

使用相機拍照

現在來進行有趣的部分 - 使用 Capacitor Camera API 在裝置上新增拍照功能。我們將從建置網頁版開始,然後做一些小的調整,使其能在行動裝置(iOS 和 Android)上運作。

為此,我們將建立自己的自訂 React hook 來管理圖庫的照片。

注意

如果您不熟悉 React Hooks,官方 React 文件中的 React Hooks 介紹 是一個很好的入門資源。

src/hooks/usePhotoGallery.ts 建立一個新檔案並開啟它。

自訂 hook 只是一個使用其他 React hooks 的函數。這就是我們要做的!我們將從匯入 React 核心、Ionic React Hooks 專案和 Capacitor 中將使用的各種 hooks 和工具開始

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 hook 公開了一個名為 takePhoto 的方法,該方法會呼叫 Capacitor 的 getPhoto 方法。

請注意這裡的奧妙:沒有平台特定的程式碼(網頁版、iOS 或 Android)!Capacitor Camera 外掛程式為我們抽象化了這一點,只留下一個方法呼叫 - getPhoto(),它將開啟裝置的相機並允許我們拍照。

我們需要採取的最後一步是從 Tab2 頁面使用新的 hook。回到 Tab2.tsx 並匯入 hook

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

在函數元件中的 return 語句之前,使用 hook 取得 takePhoto 方法的存取權

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

// snip - rest of code

儲存檔案,如果還沒執行,請執行 ionic serve 重新啟動瀏覽器中的開發伺服器。在「相片圖庫」索引標籤上,按一下「相機」按鈕。如果您的電腦有任何形式的網路攝影機,就會出現一個強制回應視窗。拍張自拍照!

A photo gallery app displaying a webcam selfie.

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

拍照後,它會消失。我們仍然需要在應用程式中顯示它,並將其儲存以供日後存取。

顯示照片

首先,我們將建立一個新的類型來定義我們的照片,其中將包含特定的中繼資料。將以下 UserPhoto 介面新增至 usePhotoGallery.ts 檔案中,放在主要函數之外的某個位置

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

回到函數的開頭(在呼叫 usePhotoGallery 之後),我們將定義一個狀態變數,以儲存使用相機拍攝的每張照片的陣列。

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

當相機完成拍照時,從 Capacitor 傳回的結果照片將儲存在 photo 變數中。我們想要建立一個新的照片物件,並將其新增至 photos 狀態陣列。我們確保不會意外變更目前的 photos 陣列,方法是建立一個新的陣列,然後呼叫 setPhotos 將陣列儲存到狀態中。更新 takePhoto 方法,並在呼叫 getPhoto 之後新增此程式碼

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

接下來,讓我們從 hook 中公開 photos 陣列。更新 return 語句以包含 photos

return {
photos,
takePhoto,
};

回到 Tab2 元件中,取得 photos 的存取權

const { photos, takePhoto } = usePhotoGallery();

將照片儲存到主要陣列後,我們可以在螢幕上顯示影像。新增一個 Grid 元件,以便在將照片新增至圖庫時,每張照片都能很好地顯示,並在 Photos 陣列中迴圈每個照片,為每個照片新增 Image 元件 (<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>

儲存所有檔案。在網頁瀏覽器中,按一下「相機」按鈕並再拍一張照片。這次,照片會顯示在相片圖庫中!

接下來,我們將新增對將照片儲存到檔案系統的支援,以便稍後可以擷取並顯示在我們的應用程式中。