You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVCam:构建相机应用——在PreviewView上方绘制网格:如何获取捕获图像边界以适配GridView尺寸

Got it, let's figure out how to get the exact bounds you need so your GridView perfectly overlays the captured image in AVCam. Depending on whether you want to match the full-resolution captured photo or just the on-screen preview frame, here are two solid approaches:

1. Get bounds for the full-resolution captured photo

If you need your grid to align with the actual photo that gets saved (not just the scaled preview on screen), you can pull the dimensions directly from the AVCapturePhoto object once a capture completes, or pre-fetch the output's default resolution.

Option 1: Fetch dimensions during capture callback

When the photo finishes processing, extract the resolution from the AVCapturePhoto instance:

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    guard error == nil else {
        // Handle error case
        return
    }
    
    // Get the full resolution of the captured photo
    let imageDimensions = photo.resolution.dimensions
    let imageSize = CGSize(width: CGFloat(imageDimensions.width), height: CGFloat(imageDimensions.height))
    
    // Adjust GridView size to match (account for aspect ratio if scaling to fit the screen)
    let aspectRatio = imageSize.width / imageSize.height
    let targetWidth = previewView.frame.width
    let targetHeight = targetWidth / aspectRatio
    
    // Update your GridView's frame or constraints
    gridView.frame = CGRect(x: 0, y: 0, width: targetWidth, height: targetHeight)
}

Option 2: Pre-fetch default output resolution

You can also get the expected resolution upfront during your AVCaptureSession setup:

if let photoOutput = captureSession.outputs.first as? AVCapturePhotoOutput {
    if let previewFormat = photoOutput.previewPhotoFormat as? [String: Any],
       let width = previewFormat[kCVPixelBufferWidthKey as String] as? Int,
       let height = previewFormat[kCVPixelBufferHeightKey as String] as? Int {
        let defaultCaptureSize = CGSize(width: width, height: height)
        // Use this size to pre-configure your GridView's initial layout
    }
}

2. Get bounds for the on-screen preview frame

If you just need the grid to cover exactly what the user sees in the PreviewView (ignoring the full photo resolution), use the AVCaptureVideoPreviewLayer to calculate the visible video rect. This accounts for aspect ratio differences between the camera's output and the screen.

// Assuming your PreviewView has a reference to its AVCaptureVideoPreviewLayer
guard let previewLayer = previewView.previewLayer else { return }

// Convert the preview layer's bounds to the actual video content rect
let videoRect = previewLayer.metadataOutputRectConverted(fromLayerRect: previewLayer.bounds)
let visibleVideoFrame = previewLayer.layerRectConverted(fromMetadataOutputRect: videoRect)

// Set your GridView's frame to match this visible area
gridView.frame = visibleVideoFrame

Handle screen rotations

Don't forget to update the GridView's frame when the device rotates. Add this to your view controller:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: { _ in
        self.updateGridViewFrame()
    })
}

private func updateGridViewFrame() {
    guard let previewLayer = previewView.previewLayer else { return }
    let videoRect = previewLayer.metadataOutputRectConverted(fromLayerRect: previewLayer.bounds)
    let visibleVideoFrame = previewLayer.layerRectConverted(fromMetadataOutputRect: videoRect)
    gridView.frame = visibleVideoFrame
}

Quick notes

  • Make sure your GridView's contentMode matches the PreviewView's (like .scaleAspectFit or .scaleAspectFill) to avoid stretching the grid.
  • If you're using Auto Layout instead of frame-based layout, adjust your width/height constraints using the calculated size instead of setting frame directly.

内容的提问来源于stack exchange,提问作者chiarotto.alessandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:23:10