Files
Android-pyApi/android_pyapi/android/hardware_camera2.py
T
shuiyu1123 bfe27fdc08 feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python
52 个模块覆盖 Android + Java + org.json 标准库
2026-06-24 11:16:16 +00:00

761 lines
30 KiB
Python

"""
Android Camera2 组件 — CameraManager, CameraDevice, CaptureRequest 等
方法签名完全对齐 Android SDK
"""
import time
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
from .._core import Stub, AndroidOnlyError, android_context, HAS_PIL
# ═══════════════════════════════════════════════════════════════
# CameraMetadata
# ═══════════════════════════════════════════════════════════════
class CameraMetadata(Stub):
"""CameraMetadata — 相机元数据基类"""
# CONTROL_AE modes
CONTROL_AE_MODE_OFF = 0
CONTROL_AE_MODE_ON = 1
CONTROL_AE_MODE_ON_AUTO_FLASH = 2
CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3
CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4
CONTROL_AE_MODE_EXTERNAL_FLASH = 5
# CONTROL_AF modes
CONTROL_AF_MODE_OFF = 0
CONTROL_AF_MODE_AUTO = 1
CONTROL_AF_MODE_MACRO = 2
CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3
CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4
CONTROL_AF_MODE_EDOF = 5
# CONTROL_AWB modes
CONTROL_AWB_MODE_OFF = 0
CONTROL_AWB_MODE_AUTO = 1
CONTROL_AWB_MODE_INCANDESCENT = 2
CONTROL_AWB_MODE_FLUORESCENT = 3
CONTROL_AWB_MODE_WARM_FLUORESCENT = 4
CONTROL_AWB_MODE_DAYLIGHT = 5
CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6
CONTROL_AWB_MODE_TWILIGHT = 7
CONTROL_AWB_MODE_SHADE = 8
# CONTROL modes
CONTROL_MODE_OFF = 0
CONTROL_MODE_AUTO = 1
CONTROL_MODE_USE_SCENE_MODE = 2
CONTROL_MODE_OFF_KEEP_STATE = 3
# FLASH modes
FLASH_MODE_OFF = 0
FLASH_MODE_SINGLE = 1
FLASH_MODE_TORCH = 2
# STATISTICS_FACE_DETECT modes
STATISTICS_FACE_DETECT_MODE_OFF = 0
STATISTICS_FACE_DETECT_MODE_SIMPLE = 1
STATISTICS_FACE_DETECT_MODE_FULL = 2
# EDGE modes
EDGE_MODE_OFF = 0
EDGE_MODE_FAST = 1
EDGE_MODE_HIGH_QUALITY = 2
EDGE_MODE_ZERO_SHUTTER_LAG = 3
# NOISE_REDUCTION modes
NOISE_REDUCTION_MODE_OFF = 0
NOISE_REDUCTION_MODE_FAST = 1
NOISE_REDUCTION_MODE_HIGH_QUALITY = 2
NOISE_REDUCTION_MODE_MINIMAL = 3
NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG = 4
# TONEMAP modes
TONEMAP_MODE_CONTRAST_CURVE = 0
TONEMAP_MODE_FAST = 1
TONEMAP_MODE_HIGH_QUALITY = 2
TONEMAP_MODE_GAMMA_VALUE = 3
TONEMAP_MODE_PRESET_CURVE = 4
# COLOR_CORRECTION modes
COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0
COLOR_CORRECTION_MODE_FAST = 1
COLOR_CORRECTION_MODE_HIGH_QUALITY = 2
# COLOR_CORRECTION_ABERRATION modes
COLOR_CORRECTION_ABERRATION_MODE_OFF = 0
COLOR_CORRECTION_ABERRATION_MODE_FAST = 1
COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY = 2
# CONTROL_AE_PRECAPTURE_TRIGGER
CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0
CONTROL_AE_PRECAPTURE_TRIGGER_START = 1
CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL = 2
# CONTROL_EFFECT modes
CONTROL_EFFECT_MODE_OFF = 0
CONTROL_EFFECT_MODE_MONO = 1
CONTROL_EFFECT_MODE_NEGATIVE = 2
CONTROL_EFFECT_MODE_SOLARIZE = 3
CONTROL_EFFECT_MODE_SEPIA = 4
CONTROL_EFFECT_MODE_POSTERIZE = 5
CONTROL_EFFECT_MODE_WHITEBOARD = 6
CONTROL_EFFECT_MODE_BLACKBOARD = 7
CONTROL_EFFECT_MODE_AQUA = 8
# CONTROL_SCENE modes
CONTROL_SCENE_MODE_DISABLED = 0
CONTROL_SCENE_MODE_FACE_PRIORITY = 1
CONTROL_SCENE_MODE_ACTION = 2
CONTROL_SCENE_MODE_PORTRAIT = 3
CONTROL_SCENE_MODE_LANDSCAPE = 4
CONTROL_SCENE_MODE_NIGHT = 5
CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6
CONTROL_SCENE_MODE_THEATRE = 7
CONTROL_SCENE_MODE_BEACH = 8
CONTROL_SCENE_MODE_SNOW = 9
CONTROL_SCENE_MODE_SUNSET = 10
CONTROL_SCENE_MODE_STEADYPHOTO = 11
CONTROL_SCENE_MODE_FIREWORKS = 12
CONTROL_SCENE_MODE_SPORTS = 13
CONTROL_SCENE_MODE_PARTY = 14
CONTROL_SCENE_MODE_CANDLELIGHT = 15
CONTROL_SCENE_MODE_BARCODE = 16
CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17
CONTROL_SCENE_MODE_HDR = 18
# CONTROL_VIDEO_STABILIZATION modes
CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0
CONTROL_VIDEO_STABILIZATION_MODE_ON = 1
# DISTORTION_CORRECTION modes
DISTORTION_CORRECTION_MODE_OFF = 0
DISTORTION_CORRECTION_MODE_FAST = 1
DISTORTION_CORRECTION_MODE_HIGH_QUALITY = 2
# HOT_PIXEL modes
HOT_PIXEL_MODE_OFF = 0
HOT_PIXEL_MODE_FAST = 1
HOT_PIXEL_MODE_HIGH_QUALITY = 2
# LENS_OPTICAL_STABILIZATION modes
LENS_OPTICAL_STABILIZATION_MODE_OFF = 0
LENS_OPTICAL_STABILIZATION_MODE_ON = 1
# LENS_FACING
LENS_FACING_FRONT = 0
LENS_FACING_BACK = 1
LENS_FACING_EXTERNAL = 2
# INFO_SUPPORTED_HARDWARE_LEVEL
INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0
INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1
INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2
INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3
INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL = 4
# ═══════════════════════════════════════════════════════════════
# CameraCharacteristics
# ═══════════════════════════════════════════════════════════════
class CameraCharacteristics(CameraMetadata):
"""CameraCharacteristics — 相机特性"""
LENS_FACING = "android.lens.facing"
SENSOR_ORIENTATION = "android.sensor.orientation"
FLASH_INFO_AVAILABLE = "android.flash.info.available"
INFO_SUPPORTED_HARDWARE_LEVEL = "android.info.supportedHardwareLevel"
SCALER_STREAM_CONFIGURATION_MAP = "android.scaler.streamConfigurationMap"
CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES = "android.control.aeAvailableTargetFpsRanges"
CONTROL_AE_AVAILABLE_MODES = "android.control.aeAvailableModes"
CONTROL_AF_AVAILABLE_MODES = "android.control.afAvailableModes"
CONTROL_AVAILABLE_EFFECTS = "android.control.availableEffects"
CONTROL_AVAILABLE_SCENE_MODES = "android.control.availableSceneModes"
CONTROL_MAX_REGIONS_AE = "android.control.maxRegionsAe"
CONTROL_MAX_REGIONS_AF = "android.control.maxRegionsAf"
CONTROL_MAX_REGIONS_AWB = "android.control.maxRegionsAwb"
JPEG_AVAILABLE_THUMBNAIL_SIZES = "android.jpeg.availableThumbnailSizes"
JPEG_MAX_SIZE = "android.jpeg.maxSize"
SENSOR_INFO_PIXEL_ARRAY_SIZE = "android.sensor.info.pixelArraySize"
SENSOR_INFO_ACTIVE_ARRAY_SIZE = "android.sensor.info.activeArraySize"
FLASH_MODE = "android.flash.mode"
def __init__(self, camera_id: str = "0"):
super().__init__()
self._properties: Dict[str, Any] = {
CameraCharacteristics.LENS_FACING: CameraCharacteristics.LENS_FACING_BACK,
CameraCharacteristics.SENSOR_ORIENTATION: 90,
CameraCharacteristics.FLASH_INFO_AVAILABLE: True,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL:
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP: {
"output_sizes": [(1920, 1080), (1280, 720), (640, 480)],
"input_sizes": [(1920, 1080)],
},
CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES: [(15, 30), (30, 30)],
CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES: [0, 1, 2, 3, 4],
CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES: [0, 1, 2, 3, 4, 5],
CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS: list(range(9)),
CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES: list(range(19)),
CameraCharacteristics.CONTROL_MAX_REGIONS_AE: 1,
CameraCharacteristics.CONTROL_MAX_REGIONS_AF: 1,
CameraCharacteristics.CONTROL_MAX_REGIONS_AWB: 0,
CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES: [(320, 240), (160, 120)],
CameraCharacteristics.JPEG_MAX_SIZE: 5000000,
CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE: (4032, 3024),
CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE: (4032, 3024),
}
def get(self, key: str) -> Any:
return self._properties.get(key)
def keys(self) -> Set[str]:
return set(self._properties.keys())
def query(self, key: str) -> Any:
return self._properties.get(key)
# ═══════════════════════════════════════════════════════════════
# CameraId
# ═══════════════════════════════════════════════════════════════
class CameraId(Stub):
"""CameraId — 相机ID封装"""
def __init__(self, id_string: str):
super().__init__()
self._id = id_string
def getId(self) -> str:
return self._id
def toString(self) -> str:
return self._id
def equals(self, other) -> bool:
if isinstance(other, CameraId):
return self._id == other._id
if isinstance(other, str):
return self._id == other
return False
def hashCode(self) -> int:
return hash(self._id)
# ═══════════════════════════════════════════════════════════════
# CameraCharacteristicsKey
# ═══════════════════════════════════════════════════════════════
class CameraCharacteristicsKey(Stub):
"""CameraCharacteristicsKey — 相机特性键"""
def __init__(self, name: str, native_type: type = object):
super().__init__()
self._name = name
self._native_type = native_type
def getName(self) -> str:
return self._name
def getNativeType(self) -> type:
return self._native_type
def equals(self, other) -> bool:
if isinstance(other, CameraCharacteristicsKey):
return self._name == other._name
return False
def hashCode(self) -> int:
return hash(self._name)
def toString(self) -> str:
return f"CameraCharacteristicsKey({self._name})"
# ═══════════════════════════════════════════════════════════════
# CaptureRequest
# ═══════════════════════════════════════════════════════════════
class CaptureRequest(CameraMetadata):
"""CaptureRequest — 捕获请求"""
CONTROL_AE_MODE = "android.control.aeMode"
CONTROL_AF_MODE = "android.control.afMode"
CONTROL_AWB_MODE = "android.control.awbMode"
CONTROL_MODE = "android.control.mode"
FLASH_MODE = "android.flash.mode"
SENSOR_EXPOSURE_TIME = "android.sensor.exposureTime"
SENSOR_SENSITIVITY = "android.sensor.sensitivity"
LENS_FOCUS_DISTANCE = "android.lens.focusDistance"
STATISTICS_FACE_DETECT_MODE = "android.statistics.faceDetectMode"
JPEG_QUALITY = "android.jpeg.quality"
JPEG_ORIENTATION = "android.jpeg.orientation"
JPEG_THUMBNAIL_QUALITY = "android.jpeg.thumbnailQuality"
JPEG_THUMBNAIL_SIZE = "android.jpeg.thumbnailSize"
SCALER_CROP_REGION = "android.scaler.cropRegion"
EDGE_MODE = "android.edge.mode"
NOISE_REDUCTION_MODE = "android.noiseReduction.mode"
TONEMAP_MODE = "android.tonemap.mode"
BLACK_LEVEL_LOCK = "android.blackLevel.lock"
CONTROL_AE_TARGET_FPS_RANGE = "android.control.aeTargetFpsRange"
CONTROL_AE_EXPOSURE_COMPENSATION = "android.control.aeExposureCompensation"
CONTROL_AE_LOCK = "android.control.aeLock"
CONTROL_AE_PRECAPTURE_TRIGGER = "android.control.aePrecaptureTrigger"
CONTROL_AWB_LOCK = "android.control.awbLock"
CONTROL_EFFECT_MODE = "android.control.effectMode"
CONTROL_SCENE_MODE = "android.control.sceneMode"
CONTROL_VIDEO_STABILIZATION_MODE = "android.control.videoStabilizationMode"
COLOR_CORRECTION_MODE = "android.colorCorrection.mode"
COLOR_CORRECTION_GAINS = "android.colorCorrection.gains"
COLOR_CORRECTION_TRANSFORM = "android.colorCorrection.transform"
COLOR_CORRECTION_ABERRATION_MODE = "android.colorCorrection.aberrationMode"
CONTROL_POST_RAW_SENSITIVITY_BOOST = "android.control.postRawSensitivityBoost"
DISTORTION_CORRECTION_MODE = "android.distortionCorrection.mode"
HOT_PIXEL_MODE = "android.hotPixel.mode"
LENS_OPTICAL_STABILIZATION_MODE = "android.lens.opticalStabilizationMode"
REQUEST_PIPELINE_MAX_DEPTH = "android.request.pipelineMaxDepth"
SENSOR_TIMESTAMP = "android.sensor.timestamp"
STATISTICS_LENS_SHADING_MAP_MODE = "android.statistics.lensShadingMapMode"
STATISTICS_OIS_DATA_MODE = "android.statistics.oisDataMode"
STATISTICS_SECTION = "android.statistics.section"
TONEMAP_CURVE = "android.tonemap.curve"
TONEMAP_GAMMA = "android.tonemap.gamma"
class Builder(Stub):
"""CaptureRequest.Builder — 捕获请求构建器"""
def __init__(self, camera_device: "CameraDevice"):
super().__init__()
self._parameters: Dict[str, Any] = {}
self._tag = None
self._camera_device = camera_device
def set(self, key: str, value: Any):
self._parameters[key] = value
def get(self, key: str) -> Any:
return self._parameters.get(key)
def setTag(self, tag: Any):
self._tag = tag
def build(self) -> "CaptureRequest":
req = CaptureRequest()
req._parameters = dict(self._parameters)
req._tag = self._tag
return req
def addTarget(self, surface):
pass
def removeTarget(self, surface):
pass
def __init__(self):
super().__init__()
self._parameters: Dict[str, Any] = {
CaptureRequest.CONTROL_AE_MODE: CameraMetadata.CONTROL_AE_MODE_ON,
CaptureRequest.CONTROL_AF_MODE: CameraMetadata.CONTROL_AF_MODE_AUTO,
CaptureRequest.CONTROL_AWB_MODE: CameraMetadata.CONTROL_AWB_MODE_AUTO,
CaptureRequest.CONTROL_MODE: CameraMetadata.CONTROL_MODE_AUTO,
CaptureRequest.FLASH_MODE: CameraMetadata.FLASH_MODE_OFF,
CaptureRequest.JPEG_QUALITY: 95,
CaptureRequest.JPEG_ORIENTATION: 0,
}
self._tag = None
self._targets: List[Any] = []
def get(self, key: str) -> Any:
return self._parameters.get(key)
def keys(self) -> Set[str]:
return set(self._parameters.keys())
def getTag(self) -> Any:
return self._tag
# ═══════════════════════════════════════════════════════════════
# CaptureResult
# ═══════════════════════════════════════════════════════════════
class CaptureResult(CameraMetadata):
"""CaptureResult — 捕获结果"""
# Same keys as CaptureRequest
CONTROL_AE_MODE = CaptureRequest.CONTROL_AE_MODE
CONTROL_AF_MODE = CaptureRequest.CONTROL_AF_MODE
CONTROL_AWB_MODE = CaptureRequest.CONTROL_AWB_MODE
CONTROL_MODE = CaptureRequest.CONTROL_MODE
FLASH_MODE = CaptureRequest.FLASH_MODE
SENSOR_EXPOSURE_TIME = CaptureRequest.SENSOR_EXPOSURE_TIME
SENSOR_SENSITIVITY = CaptureRequest.SENSOR_SENSITIVITY
LENS_FOCUS_DISTANCE = CaptureRequest.LENS_FOCUS_DISTANCE
STATISTICS_FACE_DETECT_MODE = CaptureRequest.STATISTICS_FACE_DETECT_MODE
JPEG_QUALITY = CaptureRequest.JPEG_QUALITY
JPEG_ORIENTATION = CaptureRequest.JPEG_ORIENTATION
JPEG_THUMBNAIL_QUALITY = CaptureRequest.JPEG_THUMBNAIL_QUALITY
JPEG_THUMBNAIL_SIZE = CaptureRequest.JPEG_THUMBNAIL_SIZE
SCALER_CROP_REGION = CaptureRequest.SCALER_CROP_REGION
EDGE_MODE = CaptureRequest.EDGE_MODE
NOISE_REDUCTION_MODE = CaptureRequest.NOISE_REDUCTION_MODE
TONEMAP_MODE = CaptureRequest.TONEMAP_MODE
BLACK_LEVEL_LOCK = CaptureRequest.BLACK_LEVEL_LOCK
CONTROL_AE_TARGET_FPS_RANGE = CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE
CONTROL_AE_EXPOSURE_COMPENSATION = CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION
CONTROL_AE_LOCK = CaptureRequest.CONTROL_AE_LOCK
CONTROL_AE_PRECAPTURE_TRIGGER = CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
CONTROL_AWB_LOCK = CaptureRequest.CONTROL_AWB_LOCK
CONTROL_EFFECT_MODE = CaptureRequest.CONTROL_EFFECT_MODE
CONTROL_SCENE_MODE = CaptureRequest.CONTROL_SCENE_MODE
CONTROL_VIDEO_STABILIZATION_MODE = CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE
COLOR_CORRECTION_MODE = CaptureRequest.COLOR_CORRECTION_MODE
COLOR_CORRECTION_GAINS = CaptureRequest.COLOR_CORRECTION_GAINS
COLOR_CORRECTION_TRANSFORM = CaptureRequest.COLOR_CORRECTION_TRANSFORM
COLOR_CORRECTION_ABERRATION_MODE = CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE
CONTROL_POST_RAW_SENSITIVITY_BOOST = CaptureRequest.CONTROL_POST_RAW_SENSITIVITY_BOOST
DISTORTION_CORRECTION_MODE = CaptureRequest.DISTORTION_CORRECTION_MODE
HOT_PIXEL_MODE = CaptureRequest.HOT_PIXEL_MODE
LENS_OPTICAL_STABILIZATION_MODE = CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE
REQUEST_PIPELINE_MAX_DEPTH = CaptureRequest.REQUEST_PIPELINE_MAX_DEPTH
SENSOR_TIMESTAMP = CaptureRequest.SENSOR_TIMESTAMP
STATISTICS_LENS_SHADING_MAP_MODE = CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE
STATISTICS_OIS_DATA_MODE = CaptureRequest.STATISTICS_OIS_DATA_MODE
STATISTICS_SECTION = CaptureRequest.STATISTICS_SECTION
TONEMAP_CURVE = CaptureRequest.TONEMAP_CURVE
TONEMAP_GAMMA = CaptureRequest.TONEMAP_GAMMA
def __init__(self, request: CaptureRequest = None):
super().__init__()
self._results: Dict[str, Any] = {
CaptureResult.CONTROL_AE_MODE: CameraMetadata.CONTROL_AE_MODE_ON,
CaptureResult.CONTROL_AF_MODE: CameraMetadata.CONTROL_AF_MODE_AUTO,
CaptureResult.CONTROL_AWB_MODE: CameraMetadata.CONTROL_AWB_MODE_AUTO,
CaptureResult.CONTROL_MODE: CameraMetadata.CONTROL_MODE_AUTO,
CaptureResult.FLASH_MODE: CameraMetadata.FLASH_MODE_OFF,
CaptureResult.SENSOR_EXPOSURE_TIME: 33333333,
CaptureResult.SENSOR_SENSITIVITY: 100,
CaptureResult.SENSOR_TIMESTAMP: int(time.time() * 1e9),
}
self._request = request
self._sequence_id = -1
self._frame_number = -1
def get(self, key: str) -> Any:
return self._results.get(key)
def keys(self) -> Set[str]:
return set(self._results.keys())
def getRequest(self) -> Optional[CaptureRequest]:
return self._request
def getSequenceId(self) -> int:
return self._sequence_id
def getFrameNumber(self) -> int:
return self._frame_number
# ═══════════════════════════════════════════════════════════════
# TotalCaptureResult
# ═══════════════════════════════════════════════════════════════
class TotalCaptureResult(CaptureResult):
"""TotalCaptureResult — 完整捕获结果"""
def __init__(self, request: CaptureRequest = None,
partial_results: List[CaptureResult] = None):
super().__init__(request)
self._partial_results = partial_results or []
def getPartialResults(self) -> List[CaptureResult]:
return list(self._partial_results)
# ═══════════════════════════════════════════════════════════════
# CameraCaptureSession
# ═══════════════════════════════════════════════════════════════
class CameraCaptureSession(Stub):
"""CameraCaptureSession — 捕获会话"""
class StateCallback(Stub):
"""CameraCaptureSession.StateCallback — 会话状态回调"""
def onConfigured(self, session: "CameraCaptureSession"):
pass
def onConfigureFailed(self, session: "CameraCaptureSession"):
pass
def onReady(self, session: "CameraCaptureSession"):
pass
def onActive(self, session: "CameraCaptureSession"):
pass
def onClosed(self, session: "CameraCaptureSession"):
pass
def onSurfacePrepared(self, session: "CameraCaptureSession", surface):
pass
class CaptureCallback(Stub):
"""CameraCaptureSession.CaptureCallback — 捕获回调"""
def onCaptureStarted(self, session: "CameraCaptureSession", request: CaptureRequest,
timestamp: int, frameNumber: int):
pass
def onCaptureCompleted(self, session: "CameraCaptureSession", request: CaptureRequest,
result: TotalCaptureResult):
pass
def onCaptureFailed(self, session: "CameraCaptureSession", request: CaptureRequest,
failure):
pass
def onCaptureProgressed(self, session: "CameraCaptureSession", request: CaptureRequest,
result: CaptureResult):
pass
def onCaptureSequenceCompleted(self, session: "CameraCaptureSession",
sequenceId: int, frameNumber: int):
pass
def onCaptureSequenceAborted(self, session: "CameraCaptureSession", sequenceId: int):
pass
def onCaptureBufferLost(self, session: "CameraCaptureSession", request: CaptureRequest,
target, frameNumber: int):
pass
def __init__(self, device: "CameraDevice"):
super().__init__()
self._device = device
self._closed = False
self._repeating_request = None
self._state_callback = None
self._session_id = int(time.time() * 1000)
def capture(self, request: CaptureRequest, callback: CaptureCallback = None,
handler=None) -> int:
seq_id = int(time.time() * 1000)
result = TotalCaptureResult(request)
if callback:
callback.onCaptureStarted(self, request, int(time.time() * 1e9), 0)
callback.onCaptureCompleted(self, request, result)
callback.onCaptureSequenceCompleted(self, seq_id, 0)
return seq_id
def setRepeatingRequest(self, request: CaptureRequest, callback: CaptureCallback = None,
handler=None) -> int:
self._repeating_request = request
seq_id = int(time.time() * 1000)
result = TotalCaptureResult(request)
if callback:
callback.onCaptureStarted(self, request, int(time.time() * 1e9), 0)
callback.onCaptureCompleted(self, request, result)
return seq_id
def stopRepeatingRequest(self) -> None:
self._repeating_request = None
def abortCaptures(self) -> None:
pass
def close(self):
self._closed = True
def getDevice(self) -> "CameraDevice":
return self._device
def isClosed(self) -> bool:
return self._closed
# ═══════════════════════════════════════════════════════════════
# CameraDevice
# ═══════════════════════════════════════════════════════════════
class CameraDevice(Stub):
"""CameraDevice — 相机设备"""
STATE_OPENED = 0
STATE_CLOSED = 3
STATE_DISCONNECTED = 1
STATE_ERROR = 2
class StateCallback(Stub):
"""CameraDevice.StateCallback — 设备状态回调"""
def onOpened(self, device: "CameraDevice"):
pass
def onClosed(self, device: "CameraDevice"):
pass
def onDisconnected(self, device: "CameraDevice"):
pass
def onError(self, device: "CameraDevice", error: int):
pass
def __init__(self, camera_id: str = "0"):
super().__init__()
self._id = camera_id
self._state = CameraDevice.STATE_OPENED
self._state_callback = None
self._sessions: List[CameraCaptureSession] = []
def getId(self) -> str:
return self._id
def createCaptureRequest(self, templateType: int) -> CaptureRequest.Builder:
return CaptureRequest.Builder(self)
def createCaptureSession(self, outputs: List[Any],
callback: CameraCaptureSession.StateCallback,
handler=None):
session = CameraCaptureSession(self)
session._state_callback = callback
self._sessions.append(session)
if callback:
callback.onConfigured(session)
return session
def close(self):
self._state = CameraDevice.STATE_CLOSED
for session in self._sessions:
session.close()
def getState(self) -> int:
return self._state
def toString(self) -> str:
return f"CameraDevice@{self._id}"
# ═══════════════════════════════════════════════════════════════
# CameraManager
# ═══════════════════════════════════════════════════════════════
class CameraManager(Stub):
"""CameraManager — 相机管理器"""
def __init__(self):
super().__init__()
self._cameras: Dict[str, CameraCharacteristics] = {
"0": CameraCharacteristics("0"),
}
self._open_devices: Dict[str, CameraDevice] = {}
self._availability_callbacks: List[Any] = []
self._torch_callbacks: List[Any] = []
def getCameraIdList(self) -> List[str]:
return list(self._cameras.keys())
def getCameraCharacteristics(self, cameraId: str) -> CameraCharacteristics:
if cameraId not in self._cameras:
raise AndroidOnlyError(f"Camera {cameraId} not available")
return self._cameras[cameraId]
def openCamera(self, cameraId: str, callback: CameraDevice.StateCallback,
handler=None):
if cameraId not in self._cameras:
if callback:
callback.onError(None, CameraDevice.STATE_ERROR)
return
device = CameraDevice(cameraId)
self._open_devices[cameraId] = device
if callback:
callback.onOpened(device)
def registerAvailabilityCallback(self, callback):
self._availability_callbacks.append(callback)
def unregisterAvailabilityCallback(self, callback):
if callback in self._availability_callbacks:
self._availability_callbacks.remove(callback)
def registerTorchCallback(self, callback, handler=None):
self._torch_callbacks.append(callback)
def unregisterTorchCallback(self, callback):
if callback in self._torch_callbacks:
self._torch_callbacks.remove(callback)
def setTorchMode(self, cameraId: str, enabled: bool):
pass
# ═══════════════════════════════════════════════════════════════
# CameraOfflineSession
# ═══════════════════════════════════════════════════════════════
class CameraOfflineSession(CameraCaptureSession):
"""CameraOfflineSession — 离线会话 (API 30+)"""
def __init__(self, device: CameraDevice):
super().__init__(device)
def switchToOffline(self):
pass
# ═══════════════════════════════════════════════════════════════
# CameraExtensionSession
# ═══════════════════════════════════════════════════════════════
class CameraExtensionSession(Stub):
"""CameraExtensionSession — 扩展会话 (API 31+)"""
class StateCallback(Stub):
def onConfigured(self, session: "CameraExtensionSession"):
pass
def onConfigureFailed(self, session: "CameraExtensionSession"):
pass
def onClosed(self, session: "CameraExtensionSession"):
pass
class ExtensionCaptureCallback(Stub):
def onCaptureStarted(self, session: "CameraExtensionSession", request: CaptureRequest,
timestamp: int):
pass
def onCaptureProcessStarted(self, session: "CameraExtensionSession", request: CaptureRequest):
pass
def onCaptureFailed(self, session: "CameraExtensionSession", request: CaptureRequest):
pass
def onCaptureResultAvailable(self, session: "CameraExtensionSession",
request: CaptureRequest, result: TotalCaptureResult):
pass
def __init__(self):
super().__init__()
self._closed = False
def close(self):
self._closed = True
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"CameraManager", "CameraDevice", "CameraCaptureSession",
"CaptureRequest", "CaptureResult", "CameraCharacteristics",
"CameraMetadata", "CameraId", "CameraCharacteristicsKey",
"TotalCaptureResult", "CameraOfflineSession", "CameraExtensionSession",
]