使用相機拍照
現在來進行有趣的部分 - 使用 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
重新啟動瀏覽器中的開發伺服器。在「相片圖庫」索引標籤上,按一下「相機」按鈕。如果您的電腦有任何形式的網路攝影機,就會出現一個強制回應視窗。拍張自拍照!
(您的自拍照可能比我的好得多)
拍照後,它會消失。我們仍然需要在應用程式中顯示它,並將其儲存以供日後存取。
顯示照片
首先,我們將建立一個新的類型來定義我們的照片,其中將包含特定的中繼資料。將以下 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>
儲存所有檔案。在網頁瀏覽器中,按一下「相機」按鈕並再拍一張照片。這次,照片會顯示在相片圖庫中!
接下來,我們將新增對將照片儲存到檔案系統的支援,以便稍後可以擷取並顯示在我們的應用程式中。