Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions apps/simple-camera/__tests__/visioncamera.photo.harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,58 @@ describe('VisionCamera - Photo', () => {
await session.stop()
})

it('captures three Photos in parallel with responsive capture enabled', async () => {
const session = await VisionCamera.createCameraSession(false)
const photoOutput = VisionCamera.createPhotoOutput({
targetResolution: CommonResolutions.HD_4_3,
containerFormat: 'jpeg',
quality: 0.8,
qualityPrioritization: 'balanced',
enableResponsiveCapture: true,
})
await session.configure([
{
input: backDevice,
outputs: [{ output: photoOutput, mirrorMode: 'auto' }],
constraints: [],
},
])
await session.start()

try {
const captureResults = await Promise.allSettled(
Array.from({ length: 3 }, () =>
photoOutput.capturePhoto(
{ flashMode: 'off', enableShutterSound: false },
{},
),
),
)

const capturedPhotos = captureResults.flatMap((result) =>
result.status === 'fulfilled' ? [result.value] : [],
)
try {
expect(captureResults).toHaveLength(3)
for (const result of captureResults) {
expect(result.status).toBe('fulfilled')
if (result.status === 'rejected') {
throw result.reason
}
expect(result.value.width).toBeGreaterThan(0)
expect(result.value.height).toBeGreaterThan(0)
expect(result.value.containerFormat).toBe('jpeg')
}
} finally {
for (const photo of capturedPhotos) {
photo.dispose()
}
}
} finally {
await session.stop()
}
})

it('checks and reads a native Photo pixel buffer in-memory', async (context) => {
const session = await VisionCamera.createCameraSession(false)
const photoOutput = VisionCamera.createPhotoOutput({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ final class HybridCameraPhotoOutput: HybridCameraPhotoOutputSpec, NativeCameraOu

output.maxPhotoQualityPrioritization = options.qualityPrioritization.toAVQualityPrioritization()

if #available(iOS 17.0, *),
output.isResponsiveCaptureSupported
{
output.isResponsiveCaptureEnabled = options.enableResponsiveCapture ?? false
}

if options.containerFormat == .dng {
// If we capture RAW photos, try using Apple ProRAW. If not, Bayer14 RAW will be used.
output.isAppleProRAWEnabled = output.isAppleProRAWSupported
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function usePhotoOutput({
containerFormat = 'native',
quality = 0.9,
qualityPrioritization = 'balanced',
enableResponsiveCapture = false,
previewImageTargetSize = undefined,
}: Partial<PhotoOutputOptions> = {}): CameraPhotoOutput {
// 1. Create photo output
Expand All @@ -43,13 +44,15 @@ export function usePhotoOutput({
containerFormat: containerFormat,
quality: quality,
qualityPrioritization: qualityPrioritization,
enableResponsiveCapture: enableResponsiveCapture,
previewImageTargetSize: previewImageTargetSize,
}),
[
targetResolution,
containerFormat,
quality,
qualityPrioritization,
enableResponsiveCapture,
previewImageTargetSize,
],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ export interface PhotoOutputOptions {
* @see {@linkcode CameraDevice.supportsSpeedQualityPrioritization}
*/
qualityPrioritization: QualityPrioritization
/**
* Enables or disables responsive capture.
*
* Responsive capture can reduce shutter lag and improve capture
* rates, at the cost of additional memory usage.
*
* @platform iOS
* @default false
*/
enableResponsiveCapture?: boolean
/**
* When this is set to a specific {@linkcode Size},
* a ready to display {@linkcode Image} will be delivered
Expand Down
Loading