1import {
2  PermissionResponse,
3  PermissionStatus,
4  PermissionExpiration,
5  PermissionHookOptions,
6} from 'expo-modules-core';
7import { ViewProps } from 'react-native';
8
9export enum CameraType {
10  front = 'front',
11  back = 'back',
12}
13
14export enum FlashMode {
15  on = 'on',
16  off = 'off',
17  auto = 'auto',
18  torch = 'torch',
19}
20
21export enum AutoFocus {
22  on = 'on',
23  off = 'off',
24  /**
25   * @platform web
26   */
27  auto = 'auto',
28  /**
29   * @platform web
30   */
31  singleShot = 'singleShot',
32}
33
34export enum WhiteBalance {
35  auto = 'auto',
36  /**
37   * @platform android
38   * @platform ios
39   */
40  sunny = 'sunny',
41  /**
42   * @platform android
43   * @platform ios
44   */
45  cloudy = 'cloudy',
46  /**
47   * @platform android
48   * @platform ios
49   */
50  shadow = 'shadow',
51  /**
52   * @platform android
53   * @platform ios
54   */
55  incandescent = 'incandescent',
56  /**
57   * @platform android
58   * @platform ios
59   */
60  fluorescent = 'fluorescent',
61  /**
62   * @platform web
63   */
64  continuous = 'continuous',
65  /**
66   * @platform web
67   */
68  manual = 'manual',
69}
70
71export enum ImageType {
72  png = 'png',
73  jpg = 'jpg',
74}
75
76/**
77 * This option specifies what codec to use when recording a video.
78 * @platform ios
79 */
80export enum VideoCodec {
81  H264 = 'avc1',
82  HEVC = 'hvc1',
83  JPEG = 'jpeg',
84  AppleProRes422 = 'apcn',
85  AppleProRes4444 = 'ap4h',
86}
87
88// @needsAudit
89export enum VideoStabilization {
90  off = 'off',
91  standard = 'standard',
92  cinematic = 'cinematic',
93  auto = 'auto',
94}
95
96// @needsAudit
97export enum VideoQuality {
98  '2160p' = '2160p',
99  '1080p' = '1080p',
100  '720p' = '720p',
101  '480p' = '480p',
102  '4:3' = '4:3',
103}
104
105// @needsAudit
106export type ImageParameters = {
107  imageType: ImageType;
108  quality: number | null;
109};
110
111export type ImageSize = {
112  width: number;
113  height: number;
114};
115
116export type WebCameraSettings = Partial<{
117  autoFocus: string;
118  flashMode: string;
119  whiteBalance: string;
120  exposureCompensation: number;
121  colorTemperature: number;
122  iso: number;
123  brightness: number;
124  contrast: number;
125  saturation: number;
126  sharpness: number;
127  focusDistance: number;
128  zoom: number;
129}>;
130
131export type CameraCapturedPicture = {
132  width: number;
133  height: number;
134  uri: string;
135  base64?: string;
136  exif?: Partial<MediaTrackSettings> | any;
137};
138
139// @needsAudit @docsMissing
140export type CameraPictureOptions = {
141  /**
142   * Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.
143   */
144  quality?: number;
145  /**
146   * Whether to also include the image data in Base64 format.
147   */
148  base64?: boolean;
149  /**
150   * Whether to also include the EXIF data for the image.
151   */
152  exif?: boolean;
153  /**
154   * A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured.
155   * The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it
156   * is not your case, this callback lets you skip waiting for it to be saved.
157   * @param picture
158   */
159  onPictureSaved?: (picture: CameraCapturedPicture) => void;
160  // TODO(Bacon): Is it possible to implement this in the browser?
161  /**
162   * If set to `true`, camera skips orientation adjustment and returns an image straight from the device's camera.
163   * If enabled, `quality` option is discarded (processing pipeline is skipped as a whole).
164   * Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation
165   * in the `Image` component (at the time of writing, it does not respect EXIF orientation of the images).
166   * > **Note**: Enabling `skipProcessing` would cause orientation uncertainty. `Image` component does not respect EXIF
167   * > stored orientation information, that means obtained image would be displayed wrongly (rotated by 90°, 180° or 270°).
168   * > Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide
169   * > correctly oriented images by default. To always obtain correctly oriented image disable `skipProcessing` option.
170   */
171  skipProcessing?: boolean;
172  /**
173   * @platform web
174   */
175  scale?: number;
176  /**
177   * @platform web
178   */
179  imageType?: ImageType;
180  /**
181   * @platform web
182   */
183  isImageMirror?: boolean;
184  /**
185   * @hidden
186   */
187  id?: number;
188  /**
189   * @hidden
190   */
191  fastMode?: boolean;
192};
193
194// @needsAudit
195export type CameraRecordingOptions = {
196  /**
197   * Maximum video duration in seconds.
198   */
199  maxDuration?: number;
200  /**
201   * Maximum video file size in bytes.
202   */
203  maxFileSize?: number;
204  /**
205   * Specify the quality of recorded video. Use one of [`VideoQuality.<value>`](#videoquality).
206   * Possible values: for 16:9 resolution `2160p`, `1080p`, `720p`, `480p` : `Android only` and for 4:3 `4:3` (the size is 640x480).
207   * If the chosen quality is not available for a device, the highest available is chosen.
208   */
209  quality?: number | string;
210  /**
211   * If present, video will be recorded with no sound.
212   */
213  mute?: boolean;
214  /**
215   * If `true`, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default,
216   * but you can reverse that back by setting this to `true`. On Android, this is handled in the user's device settings.
217   * @platform ios
218   */
219  mirror?: boolean;
220  /**
221   * Only works if `useCamera2Api` is set to `true`. This option specifies a desired video bitrate. For example, `5*1000*1000` would be 5Mbps.
222   * @platform android
223   */
224  videoBitrate?: number;
225  /**
226   * This option specifies what codec to use when recording the video. See [`VideoCodec`](#videocodec) for the possible values.
227   * @platform ios
228   */
229  codec?: VideoCodec;
230};
231
232export type PictureSavedListener = (event: {
233  nativeEvent: { data: CameraCapturedPicture; id: number };
234}) => void;
235
236export type CameraReadyListener = () => void;
237
238export type MountErrorListener = (event: { nativeEvent: CameraMountError }) => void;
239
240export type CameraMountError = { message: string };
241
242export type Point = {
243  x: number;
244  y: number;
245};
246
247export type BarCodePoint = Point;
248
249// @needsAudit
250export type BarCodeScanningResult = {
251  /**
252   * The barcode type.
253   */
254  type: string;
255  /**
256   * The information encoded in the bar code.
257   */
258  data: string;
259  /**
260   * Corner points of the bounding box.
261   */
262  cornerPoints?: BarCodePoint[];
263};
264
265export type Face = {
266  faceID: number;
267  bounds: {
268    origin: Point;
269    size: {
270      height: number;
271      width: number;
272    };
273  };
274  rollAngle: number;
275  yawAngle: number;
276  smilingProbability: number;
277  leftEarPosition: Point;
278  rightEarPosition: Point;
279  leftEyePosition: Point;
280  leftEyeOpenProbability: number;
281  rightEyePosition: Point;
282  rightEyeOpenProbability: number;
283  leftCheekPosition: Point;
284  rightCheekPosition: Point;
285  mouthPosition: Point;
286  leftMouthPosition: Point;
287  rightMouthPosition: Point;
288  noseBasePosition: Point;
289};
290
291export type FaceDetectionResult = { faces: Face[] };
292
293export type ConstantsType = {
294  Type: CameraType;
295  FlashMode: FlashMode;
296  AutoFocus: AutoFocus;
297  WhiteBalance: WhiteBalance;
298  VideoQuality: VideoQuality;
299  VideoStabilization: VideoStabilization;
300  VideoCodec: VideoCodec;
301};
302
303// @needsAudit
304export type CameraProps = ViewProps & {
305  /**
306   * Camera facing. Use one of `CameraType`. When `CameraType.front`, use the front-facing camera.
307   * When `CameraType.back`, use the back-facing camera.
308   * @default CameraType.back
309   */
310  type?: number | CameraType;
311  /**
312   * Camera flash mode. Use one of [`FlashMode.<value>`](#flashmode-1). When `FlashMode.on`, the flash on your device will
313   * turn on when taking a picture, when `FlashMode.off`, it won't. Setting to `FlashMode.auto` will fire flash if required,
314   * `FlashMode.torch` turns on flash during the preview.
315   * @default FlashMode.off
316   */
317  flashMode?: number | FlashMode;
318  /**
319   * Camera white balance. Use one of [`WhiteBalance.<value>`](#whitebalance). If a device does not support any of these values previous one is used.
320   * @default WhiteBalance.auto
321   */
322  whiteBalance?: number | WhiteBalance;
323  /**
324   * State of camera auto focus. Use one of [`AutoFocus.<value>`](#autofocus-1). When `AutoFocus.on`,
325   * auto focus will be enabled, when `AutoFocus.off`, it won't and focus will lock as it was in the moment of change,
326   * but it can be adjusted on some devices via `focusDepth` prop.
327   * @default AutoFocus.on
328   */
329  autoFocus?: boolean | number | AutoFocus;
330  /**
331   * A value between `0` and `1` being a percentage of device's max zoom. `0` - not zoomed, `1` - maximum zoom.
332   * @default 0
333   */
334  zoom?: number;
335  /**
336   * A string representing aspect ratio of the preview, eg. `4:3`, `16:9`, `1:1`. To check if a ratio is supported
337   * by the device use [`getSupportedRatiosAsync`](#getsupportedratiosasync).
338   * @default 4:3.
339   * @platform android
340   */
341  ratio?: string;
342  /**
343   * Distance to plane of the sharpest focus. A value between `0` and `1` where: `0` - infinity focus, `1` - focus as close as possible.
344   * For Android this is available only for some devices and when `useCamera2Api` is set to `true`.
345   * @default 0
346   */
347  focusDepth?: number;
348  /**
349   * Callback invoked when camera preview has been set.
350   */
351  onCameraReady?: () => void;
352  /**
353   * Whether to use Android's Camera2 API. See `Note` at the top of this page.
354   * @platform android
355   */
356  useCamera2Api?: boolean;
357  /**
358   * A string representing the size of pictures [`takePictureAsync`](#takepictureasync) will take.
359   * Available sizes can be fetched with [`getAvailablePictureSizesAsync`](#getavailablepicturesizesasync).
360   */
361  pictureSize?: string;
362  /**
363   * The video stabilization mode used for a video recording. Use one of [`VideoStabilization.<value>`](#videostabilization).
364   * You can read more about each stabilization type in [Apple Documentation](https://developer.apple.com/documentation/avfoundation/avcapturevideostabilizationmode).
365   * @platform ios
366   */
367  videoStabilizationMode?: number;
368  /**
369   * Callback invoked when camera preview could not been started.
370   * @param event Error object that contains a `message`.
371   */
372  onMountError?: (event: CameraMountError) => void;
373  /**
374   * Settings exposed by [`BarCodeScanner`](bar-code-scanner) module. Supported settings: **barCodeTypes**.
375   * @example
376   * ```tsx
377   * <Camera
378   *   barCodeScannerSettings={{
379   *     barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
380   *   }}
381   * />
382   * ```
383   */
384  barCodeScannerSettings?: BarCodeSettings;
385  /**
386   * Callback that is invoked when a bar code has been successfully scanned. The callback is provided with
387   * an object of the [`BarCodeScanningResult`](#barcodescanningresult) shape, where the `type`
388   * refers to the bar code type that was scanned and the `data` is the information encoded in the bar code
389   * (in this case of QR codes, this is often a URL). See [`BarCodeScanner.Constants.BarCodeType`](bar-code-scanner#supported-formats)
390   * for supported values.
391   * @param scanningResult
392   */
393  onBarCodeScanned?: (scanningResult: BarCodeScanningResult) => void;
394  /**
395   * A settings object passed directly to an underlying module providing face detection features.
396   * See [`DetectionOptions`](facedetector/#detectionoptions) in FaceDetector documentation for details.
397   */
398  faceDetectorSettings?: object;
399  /**
400   * Callback invoked with results of face detection on the preview. See [FaceDetector documentation](facedetector/#detectionresult) for details.
401   * @param faces
402   */
403  onFacesDetected?: (faces: FaceDetectionResult) => void;
404  /**
405   * A URL for an image to be shown while the camera is loading.
406   * @platform web
407   */
408  poster?: string;
409};
410
411export type CameraNativeProps = {
412  pointerEvents?: any;
413  style?: any;
414  ref?: Function;
415  onCameraReady?: CameraReadyListener;
416  onMountError?: MountErrorListener;
417  onBarCodeScanned?: (event: { nativeEvent: BarCodeScanningResult }) => void;
418  onFacesDetected?: (event: { nativeEvent: FaceDetectionResult }) => void;
419  onFaceDetectionError?: (event: { nativeEvent: Error }) => void;
420  onPictureSaved?: PictureSavedListener;
421  type?: number | string;
422  flashMode?: number | string;
423  autoFocus?: string | boolean | number;
424  focusDepth?: number;
425  zoom?: number;
426  whiteBalance?: number | string;
427  pictureSize?: string;
428  barCodeScannerSettings?: BarCodeSettings;
429  faceDetectorSettings?: object;
430  barCodeScannerEnabled?: boolean;
431  faceDetectorEnabled?: boolean;
432  ratio?: string;
433  useCamera2Api?: boolean;
434  poster?: string;
435};
436
437export type BarCodeSettings = {
438  barCodeTypes: string[];
439  interval?: number;
440};
441
442export { PermissionResponse, PermissionStatus, PermissionExpiration, PermissionHookOptions };
443