![見出し画像](https://assets.st-note.com/production/uploads/images/142931584/rectangle_large_type_2_1878edc67cc15a39a6fa76541c13f34a.png?width=800)
react-native-vision-camera の使い方
「react-native-vision-camera」の使い方をまとめました。
【注意】最新版のreact-native@0.74ではビルド失敗するため、react-native@0.73.6で動作確認しました。
前回
1. react-native-vision-camera
「react-native-vision-camera」は、React Native用のカメラライブラリです。機能は次のとおりです。
・写真と動画のキャプチャ
・QR・バーコードスキャナー
・カスタマイズ可能なデバイスとマルチカメラ (魚眼/ズーム)
・カスタマイズ可能な解像度とアスペクト比 (4k/8k)
・カスタマイズ可能な FPS (30..240 FPS)
・フレームプロセッサ (顔認識、AIオブジェクト検出、リアルタイム動画チャットなどを実行するJSワークレット)
・カメラに図形・テキスト・フィルタ・シェーダーを描画
・スムーズなズーム (再アニメーション)
・高速一時停止と再開
・HDR および夜間モード
・カスタムC++/GPUアクセラレーション動画パイプライン
2. カメラの使用手順
カメラの使用手順は、次のとおりです。
(1) パッケージのインストール。
$ npm install react-native-vision-camera
$ cd ios
$ pod install
$ cd ..
(2) iosプロジェクトの Info.plist を開き、最も外側の <dict> 内に次の行を追加。
<key>NSCameraUsageDescription</key>
<string>写真を撮るためにカメラを使用します</string>
<key>NSMicrophoneUsageDescription</key>
<string>動画を撮影するためにマイクを使用します。</string>
(3) androidプロジェクトの AndroidManifest.xml を開き、<manifest> 内に次の行を追加。
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
(4) コードの編集。
import React, { useEffect, useRef } from 'react';
import { StyleSheet, View, Text, Button, Linking } from 'react-native';
import { Camera, useCameraPermission, useCameraDevice } from 'react-native-vision-camera';
// アプリ
export default function App() {
const { hasPermission, requestPermission } = useCameraPermission(); // カメラの権限の取得
const device = useCameraDevice('back'); // カメラデバイスの取得
const camera = useRef<Camera>(null); // カメラの参照の取得
// 初回起動時に呼ばれる
useEffect(() => {
if (hasPermission === false) {
// 権限を要求
requestPermission();
}
}, []);
// 写真撮影ボタン押下時に呼ばれる
const takePhoto = async () => {
if (camera.current) {
const photo = await camera.current.takePhoto();
console.log(photo);
}
};
// デバイスなし
if (device == null) {
return <View />;
}
// 権限を拒否
if (hasPermission == false) {
return (
<View>
<Text>カメラの権限が必要です。</Text>
<Button title="設定を開く" onPress={() => Linking.openSettings()} />
</View>
);
}
// 権限を許可
return (
<View style={styles.container}>
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
ref={camera}
photo={true}
/>
<Button title="撮影" onPress={takePhoto} />
</View>
);
}
// スタイル
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-end',
},
});
◎ カメラの権限の取得
カメラを使用する場合はuseCameraPermission()、マイクを使用する場合はuseMicrophonePermission()をフックします。
これらは次の3つの状態を持ちます。
(1) アプリの初回起動時、hasPermission は false です。今すぐ requestPermission() を呼び出してください。
(2) ユーザーが許可した場合は、hasPermission は true です。<Camera> ビューでプレビューを表示してください。
(3) ユーザーが拒否した場合は、hasPermission は false です。Linking API を使用してアプリ設定を開き、カメラ権限を付与する必要があることをユーザーに伝えます。
◎ プレビューの表示
useCameraDevice()でカメラデバイス、useRef<Camera>()でカメラの参照をを取得し、<Camera>でカメラのビューを表示します。
(5) 実行。
撮影ボタンを押すと、photoオブジェクトの情報がログ出力されます。
![](https://assets.st-note.com/img/1717482364963-GGV1BAJTsp.png?width=800)
{"height": 3024, "isMirrored": false, "isRawPhoto": false, "orientation": "portrait", "path": "/data/user/0/com.awesomeproject/cache/mrousavy-9174041254606867901.jpg", "width": 4032}
3. カメラデバイス
「カメラデバイス」は、写真・動画の撮影に使用できる物理 (または仮想) デバイスです。
3-1. 物理カメラデバイス
「物理カメラデバイス」は、携帯電話のカメラレンズです。物理カメラデバイスごとに、キャプチャ形式、解像度、ズームレベルなどの仕様が異なります。一部の携帯電話には、複数の物理カメラデバイスが搭載されています。
【例】
・Backside Wide-Angle Camera
・Frontside Wide-Angle Camera (FaceTime HD)
・Ultra-Wide-Angle back camera
3-2. 仮想カメラデバイス
「仮想カメラデバイス」は、1つ以上の物理カメラデバイスを組み合わせたもので、ズーム中に仮想デバイスを切り替える機能や、すべての物理カメラからの写真を組み合わせて、より高品質の画像を生成する機能などを提供します。
【例】
・Triple-Camera
・Dual-Wide-Angle Camera
3-3. カメラデバイスの取得
カメラデバイスはuseCameraDevice()で取得できます。
const device = useCameraDevice('back')
カメラデバイスは次の仕様で構成されます。
console.log(device)で確認できます。
・id : カメラデバイスのID
・position : 携帯電話に対する位置
・back : 携帯電話の背面
・front : 携帯電話の前面
・external : 外部デバイス
・physicalDevices : レンズ
・ultra-wide-angle-camera : 魚眼カメラ (0.5x zoom)
・wide-angle-camera : デフォルトカメラ (1x zoom)
・telephoto-camera : ズームインカメラ (3x zoom)
・sensorOrientation : 携帯電話に対する向き
・landscape-left : 横長左向き (90° 回転)
・minZoom : 最小ズーム係数 (1)
・maxZoom : 最大ズーム係数 (8)
・neutralZoom : minZoom と maxZoom の間の値 (1)
・formats : サポートするCamera Formatsのリスト
・Video Resolution
・Photo Resolution
・FPS
・Video Stabilization Mode参照
・Pixel Format参照
4. プレビュー
<Camera> で、カメラのプレビューをレンダリングします。
ほとんどの場合は style={{ flex: 1 }} で済みます。
4-1. ライフサイクル
CameraのisActiveで、セッションを一時停止しながら、ウォームな状態に維持することができます。これは、カメラを完全にアンマウントするよりも望ましい方法です。セッションの再開は、カメラビューを再マウントするよりもはるかに高速です。
ユーザーがアプリを最小化した時 (useAppState())、新しい画面に移動した時 (useIsFocused()) に、カメラを一時停止することができます。
function App() {
const isFocused = useIsFocused()
const appState = useAppState()
const isActive = isFocused && appState === "active"
return <Camera {...props} isActive={isActive} />
}
4-2. リサイズモード
「cover」(ビューを埋めるために中央に切り取る) または「contain」(ビュー内に収まるようにスケーリング) のいずれかを指定します。
4-3. プレビューの無効化
preview={false} で無効化できます。
4-4. FPS
fpsでフレームレートを指定できます。デフォルトは30FPSです。
<Camera {...props} fps={60} />
4-5. 解像度
iOSでは動画解像度でプレビュー解像度が決まるため、動画解像度が低い場合は、プレビュー解像度も低くなります。
const lowResolutionFormat = useCameraFormat(device, [
{ videoResolution: { width: 640, height: 480 } },
])
Androidでは、プレビューは常にフル HD またはプレビューのサイズのいずれか小さい方になります。
4-6. オーバーレイとマスク
Androidでは、プレビュービューは androidPreviewViewType を通じて制御可能な2つの実装モードをサポートしています。
・surface-view : レンダリングにSurfaceView を使用。これはより効率的で、HDRレンダリングをサポートするが、マスク、透明度、回転、クリッピングをサポートしない
・texture-view : レンダリングにTextureViewを使用。これは効率が低く、HDRレンダリングはサポートしないが、マスク、透明度、回転、クリッピングをサポートする
<Camera {...props} androidPreviewViewType="texture-view" />
5. 撮影
5-1. 写真撮影
写真撮影には、写真キャプチャを有効にする必要があります。
<Camera
{...props}
photo={true}
/>
takePhoto() で撮影します。
const photo = await camera.current.takePhoto()
TakePhotoOptionsでフラッシュの有効化、シャッター音の無効化などをカスタマイズできます。
この関数は、一時フォルダに保存される PhotoFile を返します。この PhotoFile は、<Image> または <FastImage> を使用して表示したり、バックエンドにアップロードしたり、react-native-cameraroll でカメラロールに保存したりできます。
5-2. フォーカス
カメラで特定ポイントをフォーカスするには、focus()を使用します。
await camera.current.focus({ x: tapEvent.x, y: tapEvent.y })
5-3. 解像度
カスタム解像度を使用する場合は、Cameraのformatを設定します。
const format = useCameraFormat(device, [
{ photoResolution: { width: 1280, height: 720 } }
])
return <Camera {...props} format={format} />
5-4. フラッシュ
takePhoto()には、auto (フラッシュを自動的に有効)、on (常に有効)、off (有効にしない)を設定できます。
const photo = await camera.current.takePhoto({
flash: 'on' // 'auto' | 'off'
})
フラッシュは hasFlashがtrueであるカメラデバイスでのみ使用できるます。
5-5. 写真品質バランス
photoQualityBalanceで、速度と品質どちらを優先するか設定できます。
return <Camera {...props} photoQualityBalance="speed" />
5-6. スナップショット
スナップショットは、最大16ミリ秒の速度で写真撮影できます。カメラのプレビューから取得され、AE/AF/AWB のプリキャプチャシーケンスは実行されません。
const snapshot = await camera.current.takeSnapshot({
quality: 90
})
5-7. 写真のカメラロール保存
写真をカメラロールに保存するには、react-native-cameraroll を使用できます。
const file = await camera.current.takePhoto()
await CameraRoll.save(`file://${file.path}`, {
type: 'photo',
})
5-8. 写真のデータの取得
写真のピクセルデータを取得するには、ローカルファイルをfetch() でBlobとして読み取ります。
const file = await camera.current.takePhoto()
const result = await fetch(`file://${file.path}`)
const data = await result.blob();
次回
この記事が気に入ったらサポートをしてみませんか?