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

如何在Flutter camera v0.11.0插件中设置AWB等相机低级参数?

解决方案:在Flutter camera v0.11.0中设置相机低级参数

由于官方camera: ^0.11.0+1插件本身不提供AWB、ISO、曝光这类低级参数的API,你需要通过**自定义平台通道(Platform Channel)**直接调用Android和iOS的原生相机API来实现,具体步骤如下:

1. Flutter层定义方法通道

创建工具类封装与原生交互的方法,用于传递参数设置指令:

import 'package:flutter/services.dart';

class CameraAdvancedSettings {
  static const MethodChannel _channel = MethodChannel('camera_advanced_settings');

  // 设置自动白平衡模式
  static Future<void> setWhiteBalanceMode(int mode) async {
    await _channel.invokeMethod('setWhiteBalanceMode', {'mode': mode});
  }

  // 设置ISO值
  static Future<void> setISO(int iso) async {
    await _channel.invokeMethod('setISO', {'iso': iso});
  }

  // 设置曝光补偿
  static Future<void> setExposureCompensation(int compensation) async {
    await _channel.invokeMethod('setExposureCompensation', {'compensation': compensation});
  }
}

2. Android原生实现

在Android项目的MainActivity中实现通道方法,调用Camera2 API修改相机参数:

import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CaptureRequest
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private lateinit var cameraDevice: CameraDevice
    private lateinit var captureSession: CameraCaptureSession
    private val CHANNEL = "camera_advanced_settings"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "setWhiteBalanceMode" -> {
                    val mode = call.argument<Int>("mode") ?: CaptureRequest.CONTROL_AWB_MODE_AUTO
                    val requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
                    requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, mode)
                    captureSession.setRepeatingRequest(requestBuilder.build(), null, null)
                    result.success(null)
                }
                "setISO" -> {
                    val iso = call.argument<Int>("iso") ?: 100
                    val requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
                    requestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, iso)
                    captureSession.setRepeatingRequest(requestBuilder.build(), null, null)
                    result.success(null)
                }
                "setExposureCompensation" -> {
                    val compensation = call.argument<Int>("compensation") ?: 0
                    val requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
                    requestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, compensation)
                    captureSession.setRepeatingRequest(requestBuilder.build(), null, null)
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }
    }

    // 注意:需先通过camera插件的初始化回调获取cameraDevice和captureSession实例
}

3. iOS原生实现

在iOS项目的AppDelegate中实现通道方法,调用AVFoundation框架修改参数:

import UIKit
import Flutter
import AVFoundation

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private let CHANNEL = "camera_advanced_settings"
    private var deviceInput: AVCaptureDeviceInput?

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
            guard let self = self, let device = self.deviceInput?.device else {
                result(FlutterError(code: "DEVICE_NULL", message: "未获取相机设备", details: nil))
                return
            }
            switch call.method {
            case "setWhiteBalanceMode":
                guard let modeRaw = call.arguments as? Int else {
                    result(FlutterError(code: "INVALID_ARG", message: "参数无效", details: nil))
                    return
                }
                let mode = AVCaptureDevice.WhiteBalanceMode(rawValue: modeRaw) ?? .autoWhiteBalance
                do {
                    try device.lockForConfiguration()
                    device.whiteBalanceMode = mode
                    device.unlockForConfiguration()
                    result(nil)
                } catch {
                    result(FlutterError(code: "CONFIG_ERROR", message: "无法设置白平衡", details: error.localizedDescription))
                }
            case "setISO":
                guard let iso = call.arguments as? Int else {
                    result(FlutterError(code: "INVALID_ARG", message: "参数无效", details: nil))
                    return
                }
                do {
                    try device.lockForConfiguration()
                    device.setExposureModeCustom(duration: device.exposureDuration, iso: Float(iso), completionHandler: nil)
                    device.unlockForConfiguration()
                    result(nil)
                } catch {
                    result(FlutterError(code: "CONFIG_ERROR", message: "无法设置ISO", details: error.localizedDescription))
                }
            case "setExposureCompensation":
                guard let compensation = call.arguments as? Int else {
                    result(FlutterError(code: "INVALID_ARG", message: "参数无效", details: nil))
                    return
                }
                do {
                    try device.lockForConfiguration()
                    device.exposureTargetBias = Float(compensation) * device.exposureTargetBiasStep
                    device.unlockForConfiguration()
                    result(nil)
                } catch {
                    result(FlutterError(code: "CONFIG_ERROR", message: "无法设置曝光补偿", details: error.localizedDescription))
                }
            default:
                result(FlutterMethodNotImplemented)
            }
        })
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    // 注意:需从camera插件的初始化回调中获取AVCaptureDeviceInput实例
}

4. 核心注意事项

  • 必须先获取原生相机的实例对象(Android的CameraDevice、iOS的AVCaptureDevice),可通过监听官方camera插件的相机初始化回调来获取,避免使用反射(兼容性风险高)。
  • 不同设备支持的参数范围不同,设置前需先校验:Android通过CameraCharacteristics查询支持的AWB模式、ISO范围;iOS通过AVCaptureDevice的isWhiteBalanceModeSupported(_:)等方法判断。
  • 录制视频时,需确保参数设置在视频录制会话模板(Android的TEMPLATE_RECORD、iOS的视频捕获配置)中生效,避免参数被系统重置。

内容的提问来源于stack exchange,提问作者P.C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:02:06