1import {
2  PermissionResponse,
3  PermissionStatus,
4  PermissionExpiration,
5  PermissionHookOptions,
6} from 'expo-modules-core';
7import type { 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/**
89 * This option specifies the stabilization mode to use when recording a video.
90 * @platform ios
91 */
92export enum VideoStabilization {
93  off = 'off',
94  standard = 'standard',
95  cinematic = 'cinematic',
96  auto = 'auto',
97}
98
99// @docsMissing
100export enum VideoQuality {
101  '2160p' = '2160p',
102  '1080p' = '1080p',
103  '720p' = '720p',
104  '480p' = '480p',
105  '4:3' = '4:3',
106}
107
108export enum CameraOrientation {
109  portrait = 1,
110  portraitUpsideDown = 2,
111  landscapeLeft = 3,
112  landscapeRight = 4,
113}
114
115// @docsMissing
116/**
117 * @hidden We do not expose related web methods in docs.
118 * @platform web
119 */
120export type ImageSize = {
121  width: number;
122  height: number;
123};
124
125// @docsMissing
126/**
127 * @hidden We do not expose related web methods in docs.
128 * @platform web
129 */
130export type WebCameraSettings = {
131  autoFocus?: string;
132  flashMode?: string;
133  whiteBalance?: string;
134  exposureCompensation?: number;
135  colorTemperature?: number;
136  iso?: number;
137  brightness?: number;
138  contrast?: number;
139  saturation?: number;
140  sharpness?: number;
141  focusDistance?: number;
142  zoom?: number;
143};
144
145// @needsAudit
146export type CameraCapturedPicture = {
147  /**
148   * Captured image width.
149   */
150  width: number;
151  /**
152   * Captured image height.
153   */
154  height: number;
155  /**
156   * On web, the value of `uri` is the same as `base64` because file system URLs are not supported in the browser.
157   */
158  uri: string;
159  /**
160   * A Base64 representation of the image.
161   */
162  base64?: string;
163  /**
164   * On Android and iOS this object may include various fields based on the device and operating system.
165   * On web, it is a partial representation of the [`MediaTrackSettings`](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings) dictionary.
166   */
167  exif?: Partial<MediaTrackSettings> | any;
168};
169
170// @needsAudit
171export type CameraPictureOptions = {
172  /**
173   * Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.
174   */
175  quality?: number;
176  /**
177   * Whether to also include the image data in Base64 format.
178   */
179  base64?: boolean;
180  /**
181   * Whether to also include the EXIF data for the image.
182   */
183  exif?: boolean;
184  /**
185   * Additional EXIF data to be included for the image. Only useful when `exif` option is set to `true`.
186   * @platform android
187   * @platform ios
188   */
189  additionalExif?: { [name: string]: any };
190  /**
191   * A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured.
192   * The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it
193   * is not your case, this callback lets you skip waiting for it to be saved.
194   * @param picture
195   */
196  onPictureSaved?: (picture: CameraCapturedPicture) => void;
197  // TODO(Bacon): Is it possible to implement this in the browser?
198  /**
199   * If set to `true`, camera skips orientation adjustment and returns an image straight from the device's camera.
200   * If enabled, `quality` option is discarded (processing pipeline is skipped as a whole).
201   * Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation
202   * in the `Image` component (at the time of writing, it does not respect EXIF orientation of the images).
203   * > **Note**: Enabling `skipProcessing` would cause orientation uncertainty. `Image` component does not respect EXIF
204   * > stored orientation information, that means obtained image would be displayed wrongly (rotated by 90°, 180° or 270°).
205   * > Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide
206   * > correctly oriented images by default. To always obtain correctly oriented image disable `skipProcessing` option.
207   */
208  skipProcessing?: boolean;
209  /**
210   * @platform web
211   */
212  scale?: number;
213  /**
214   * @platform web
215   */
216  imageType?: ImageType;
217  /**
218   * @platform web
219   */
220  isImageMirror?: boolean;
221  /**
222   * @hidden
223   */
224  id?: number;
225  /**
226   * @hidden
227   */
228  fastMode?: boolean;
229  /**
230   * @hidden
231   */
232  maxDownsampling?: number;
233};
234
235// @needsAudit
236export type CameraRecordingOptions = {
237  /**
238   * Maximum video duration in seconds.
239   */
240  maxDuration?: number;
241  /**
242   * Maximum video file size in bytes.
243   */
244  maxFileSize?: number;
245  /**
246   * Specify the quality of recorded video. Use one of [`VideoQuality.<value>`](#videoquality).
247   * Possible values: for 16:9 resolution `2160p`, `1080p`, `720p`, `480p` : `Android only` and for 4:3 `4:3` (the size is 640x480).
248   * If the chosen quality is not available for a device, the highest available is chosen.
249   */
250  quality?: number | string;
251  /**
252   * If present, video will be recorded with no sound.
253   */
254  mute?: boolean;
255  /**
256   * If `true`, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default,
257   * but you can reverse that back by setting this to `true`. On Android, this is handled in the user's device settings.
258   * @platform ios
259   */
260  mirror?: boolean;
261  /**
262   * Only works if `useCamera2Api` is set to `true`. This option specifies a desired video bitrate. For example, `5*1000*1000` would be 5Mbps.
263   * @platform android
264   */
265  videoBitrate?: number;
266  /**
267   * This option specifies what codec to use when recording the video. See [`VideoCodec`](#videocodec) for the possible values.
268   * @platform ios
269   */
270  codec?: VideoCodec;
271};
272
273/**
274 * @hidden
275 */
276export type PictureSavedListener = (event: {
277  nativeEvent: { data: CameraCapturedPicture; id: number };
278}) => void;
279
280/**
281 * @hidden
282 */
283export type CameraReadyListener = () => void;
284
285/**
286 * @hidden
287 */
288export type ResponsiveOrientationChangedListener = (event: {
289  nativeEvent: ResponsiveOrientationChanged;
290}) => void;
291
292export type ResponsiveOrientationChanged = { orientation: CameraOrientation };
293
294/**
295 * @hidden
296 */
297export type MountErrorListener = (event: { nativeEvent: CameraMountError }) => void;
298
299// @docsMissing
300export type CameraMountError = { message: string };
301
302// @docsMissing
303export type Point = {
304  x: number;
305  y: number;
306};
307
308export type BarCodeSize = {
309  /**
310   * The height value.
311   */
312  height: number;
313  /**
314   * The width value.
315   */
316  width: number;
317};
318
319/**
320 * These coordinates are represented in the coordinate space of the camera source (e.g. when you
321 * are using the camera view, these values are adjusted to the dimensions of the view).
322 */
323export type BarCodePoint = Point;
324
325export type BarCodeBounds = {
326  /**
327   * The origin point of the bounding box.
328   */
329  origin: BarCodePoint;
330  /**
331   * The size of the bounding box.
332   */
333  size: BarCodeSize;
334};
335
336// @needsAudit
337export type BarCodeScanningResult = {
338  /**
339   * The barcode type.
340   */
341  type: string;
342  /**
343   * The information encoded in the bar code.
344   */
345  data: string;
346  /**
347   * Corner points of the bounding box.
348   * `cornerPoints` is not always available and may be empty. On iOS, for `code39` and `pdf417`
349   * you don't get this value.
350   */
351  cornerPoints: BarCodePoint[];
352  /**
353   * The [BarCodeBounds](#barcodebounds) object.
354   * `bounds` in some case will be representing an empty rectangle.
355   * Moreover, `bounds` doesn't have to bound the whole barcode.
356   * For some types, they will represent the area used by the scanner.
357   */
358  bounds: BarCodeBounds;
359};
360
361export type FaceDetectionResult = {
362  /**
363   * Array of objects representing results of face detection.
364   * See [`FaceFeature`](facedetector/#facefeature) in FaceDetector documentation for more details.
365   */
366  faces: object[];
367};
368
369/**
370 * @hidden
371 */
372export type ConstantsType = {
373  Type: CameraType;
374  FlashMode: FlashMode;
375  AutoFocus: AutoFocus;
376  WhiteBalance: WhiteBalance;
377  VideoQuality: VideoQuality;
378  VideoStabilization: VideoStabilization;
379  VideoCodec: VideoCodec;
380};
381
382// @needsAudit
383export type CameraProps = ViewProps & {
384  /**
385   * Camera facing. Use one of `CameraType`. When `CameraType.front`, use the front-facing camera.
386   * When `CameraType.back`, use the back-facing camera.
387   * @default CameraType.back
388   */
389  type?: number | CameraType;
390  /**
391   * Camera flash mode. Use one of [`FlashMode.<value>`](#flashmode-1). When `FlashMode.on`, the flash on your device will
392   * turn on when taking a picture, when `FlashMode.off`, it won't. Setting to `FlashMode.auto` will fire flash if required,
393   * `FlashMode.torch` turns on flash during the preview.
394   * @default FlashMode.off
395   */
396  flashMode?: number | FlashMode;
397  /**
398   * Camera white balance. Use one of [`WhiteBalance.<value>`](#whitebalance). If a device does not support any of these values previous one is used.
399   * @default WhiteBalance.auto
400   */
401  whiteBalance?: number | WhiteBalance;
402  /**
403   * State of camera auto focus. Use one of [`AutoFocus.<value>`](#autofocus-1). When `AutoFocus.on`,
404   * auto focus will be enabled, when `AutoFocus.off`, it won't and focus will lock as it was in the moment of change,
405   * but it can be adjusted on some devices via `focusDepth` prop.
406   * @default AutoFocus.on
407   */
408  autoFocus?: boolean | number | AutoFocus;
409  /**
410   * A value between `0` and `1` being a percentage of device's max zoom. `0` - not zoomed, `1` - maximum zoom.
411   * @default 0
412   */
413  zoom?: number;
414  /**
415   * A string representing aspect ratio of the preview, eg. `4:3`, `16:9`, `1:1`. To check if a ratio is supported
416   * by the device use [`getSupportedRatiosAsync`](#getsupportedratiosasync).
417   * @default 4:3
418   * @platform android
419   */
420  ratio?: string;
421  /**
422   * Distance to plane of the sharpest focus. A value between `0` and `1` where: `0` - infinity focus, `1` - focus as close as possible.
423   * For Android this is available only for some devices and when `useCamera2Api` is set to `true`.
424   * @default 0
425   */
426  focusDepth?: number;
427  /**
428   * Callback invoked when camera preview has been set.
429   */
430  onCameraReady?: () => void;
431  /**
432   * Whether to use Android's Camera2 API. See `Note` at the top of this page.
433   * @platform android
434   */
435  useCamera2Api?: boolean;
436  /**
437   * A string representing the size of pictures [`takePictureAsync`](#takepictureasyncoptions) will take.
438   * Available sizes can be fetched with [`getAvailablePictureSizesAsync`](#getavailablepicturesizesasyncratio).
439   */
440  pictureSize?: string;
441  /**
442   * The video stabilization mode used for a video recording. Use one of [`VideoStabilization.<value>`](#videostabilization).
443   * You can read more about each stabilization type in [Apple Documentation](https://developer.apple.com/documentation/avfoundation/avcapturevideostabilizationmode).
444   * @platform ios
445   */
446  videoStabilizationMode?: VideoStabilization;
447  /**
448   * Callback invoked when camera preview could not been started.
449   * @param event Error object that contains a `message`.
450   */
451  onMountError?: (event: CameraMountError) => void;
452  /**
453   * Settings exposed by [`BarCodeScanner`](bar-code-scanner) module. Supported settings: **barCodeTypes**.
454   * @example
455   * ```tsx
456   * <Camera
457   *   barCodeScannerSettings={{
458   *     barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
459   *   }}
460   * />
461   * ```
462   */
463  barCodeScannerSettings?: BarCodeSettings;
464  /**
465   * Callback that is invoked when a bar code has been successfully scanned. The callback is provided with
466   * an object of the [`BarCodeScanningResult`](#barcodescanningresult) shape, where the `type`
467   * refers to the bar code type that was scanned and the `data` is the information encoded in the bar code
468   * (in this case of QR codes, this is often a URL). See [`BarCodeScanner.Constants.BarCodeType`](bar-code-scanner#supported-formats)
469   * for supported values.
470   * @param scanningResult
471   */
472  onBarCodeScanned?: (scanningResult: BarCodeScanningResult) => void;
473  /**
474   * A settings object passed directly to an underlying module providing face detection features.
475   * See [`DetectionOptions`](facedetector/#detectionoptions) in FaceDetector documentation for details.
476   */
477  faceDetectorSettings?: object;
478  /**
479   * Callback invoked with results of face detection on the preview.
480   * See [`DetectionResult`](facedetector/#detectionresult) in FaceDetector documentation for more details.
481   * @param faces
482   */
483  onFacesDetected?: (faces: FaceDetectionResult) => void;
484  /**
485   * A URL for an image to be shown while the camera is loading.
486   * @platform web
487   */
488  poster?: string;
489  /**
490   * Whether to allow responsive orientation of the camera when the screen orientation is locked (i.e. when set to `true`
491   * landscape photos will be taken if the device is turned that way, even if the app or device orientation is locked to portrait)
492   * @platform ios
493   */
494  responsiveOrientationWhenOrientationLocked?: boolean;
495  /**
496   * Callback invoked when responsive orientation changes. Only applicable if `responsiveOrientationWhenOrientationLocked` is `true`
497   * @param event result object that contains updated orientation of camera
498   * @platform ios
499   */
500  onResponsiveOrientationChanged?: (event: ResponsiveOrientationChanged) => void;
501};
502
503/**
504 * @hidden
505 */
506export type CameraNativeProps = {
507  pointerEvents?: any;
508  style?: any;
509  ref?: Function;
510  onCameraReady?: CameraReadyListener;
511  onMountError?: MountErrorListener;
512  onBarCodeScanned?: (event: { nativeEvent: BarCodeScanningResult }) => void;
513  onFacesDetected?: (event: { nativeEvent: FaceDetectionResult }) => void;
514  onFaceDetectionError?: (event: { nativeEvent: Error }) => void;
515  onPictureSaved?: PictureSavedListener;
516  onResponsiveOrientationChanged?: ResponsiveOrientationChangedListener;
517  type?: number | string;
518  flashMode?: number | string;
519  autoFocus?: string | boolean | number;
520  focusDepth?: number;
521  zoom?: number;
522  whiteBalance?: number | string;
523  pictureSize?: string;
524  barCodeScannerSettings?: BarCodeSettings;
525  faceDetectorSettings?: object;
526  barCodeScannerEnabled?: boolean;
527  faceDetectorEnabled?: boolean;
528  ratio?: string;
529  useCamera2Api?: boolean;
530  poster?: string;
531  responsiveOrientationWhenOrientationLocked?: boolean;
532};
533
534// @docsMissing
535export type BarCodeSettings = {
536  barCodeTypes: string[];
537  interval?: number;
538};
539
540export { PermissionResponse, PermissionStatus, PermissionExpiration, PermissionHookOptions };
541