先日、Instagram で夜間モードを使用して暗い場所でも美しい写真を撮影できるようになったことをご紹介しました。この機能は、複数の露出を組み合わせて高品質の静止画を作成する時間がある静止画に最適です。しかし、写真と写真の間の瞬間はどうでしょうか?ユーザーは、シャッター ボタンを押す瞬間だけでなく、カメラを操作する必要があります。また、プレビューを使用してシーンを構成したり、QR コードをスキャンしたりします。
今回は、リアルタイムのカメラ ストリームを明るくする強力な機能であるLow Light Boost(LLB)について詳しく説明します。静止画のキャプチャ時間が必要な夜間モードとは異なり、Low Light Boost はライブ プレビューと動画録画で瞬時に動作します。LLB は、利用可能な光に基づいて必要な明るさ調整を自動的に行うため、あらゆる環境に最適化されています。
最近のアップデートにより、LLB を使用すると、Instagram ユーザーは完璧なショットを撮影できます。また、既存の夜間モードの実装により、ユーザーが 1 年以上楽しんでいるのと同じ高画質の低照度写真が撮影できます。
リアルタイムの明るさが重要な理由
夜間モードは最終的な画質の向上を目的としていますが、Low Light Boost は暗い環境での使いやすさとインタラクティビティを目的としています。もう 1 つ考慮すべき重要な要素は、LLB と夜間モードは非常にうまく連携しますが、個別に使用できることです。これらのユースケースの一部では、夜間モードの写真が必要ない場合でも、LLB には独自の価値があります。LLB がユーザー エクスペリエンスをどのように改善するかを以下に示します。
- フレーミングとキャプチャの改善: 薄暗いシーンでは、標準のカメラ プレビューが真っ黒になることがあります。LLB はビューファインダーを明るくするため、ユーザーはシャッター ボタンを押す前にフレーミングを確認できます。このエクスペリエンスでは、夜間モードを使用して最高の画質の低照度写真を得ることも、LLB を使用して「見たまま」の写真を得ることもできます。
- 信頼性の高いスキャン: QR コードはどこにでもありますが、暗いレストランや屋内駐車場でスキャンするのは難しいことがよくあります。カメラフィードが大幅に明るくなると、スキャン アルゴリズムは非常に暗い環境でも QR コードを確実に検出してデコードできます。
- インタラクションの強化: ライブ動画インタラクション(AI アシスタントやビデオ通話など)を含むアプリの場合、LLB は認識可能な情報の量を増やし、コンピュータ ビジョン モデルが処理するのに十分なデータを確保します。
Instagram での違い
Android 版 Instagram アプリのエンジニアリング チームは、ユーザーに最先端のカメラ エクスペリエンスを提供するために常に尽力しています。上の例では、LLB が Google Pixel 10 Pro にどのような違いをもたらすかを確認できます。
これにより、ユーザー エクスペリエンスがどのように変わるか簡単に想像できます。ユーザーがキャプチャしている内容を確認できない場合、キャプチャを中止する可能性が高くなります。
実装の選択
Low Light Boost を実装して、幅広いデバイスで最高のユーザー エクスペリエンスを提供するには、次の 2 つの方法があります。
- Low Light Boost AE モード: これはハードウェア レイヤの自動露出モードです。画像信号処理装置(ISP)パイプラインを直接調整するため、最高の品質とパフォーマンスを実現します。 最初に必ず確認してください。
- Google Low Light Boost: デバイスが AE モードをサポートしていない場合は、Google Play 開発者サービスから提供されるこのソフトウェア ベースのソリューションにフォールバックできます。カメラ ストリームに後処理を適用して明るくします。オールソフトウェア ソリューションとして、より多くのデバイスで利用できるため、この実装により、LLB を搭載したより多くのデバイスにリーチできます。
Low Light Boost AE モード(ハードウェア)
メカニズム:
このモードは Android 15 以降を搭載したデバイスでサポートされており、OEM が HAL でサポートを実装している必要があります(現在は Google Pixel 10 デバイスで利用可能)。カメラの画像信号処理装置(ISP)と直接統合されます。CaptureRequest.CONTROL_AE_MODE を CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY に設定すると、カメラ システムが制御します。
動作:
HAL/ISP はシーンを分析し、センサーと処理のパラメータを調整します。多くの場合、露出時間を長くして画像を明るくします。デジタル センサーのゲイン(ISO)を上げるのではなく、露出時間を長くすることで、センサーがより多くの光情報をキャプチャできるため、信号対雑音比(SNR)が大幅に向上したフレームが得られます。
メリット:
専用のハードウェア パスを利用するため、画質と電力効率が向上する可能性があります。
トレードオフ:
センサーが光をキャプチャするのに時間がかかるため、非常に暗い場所ではフレームレートが低下する可能性があります。非常に暗い場所では、フレームレートが 10 FPS まで低下することがあります。
Google Low Light Boost(Google Play 開発者サービス経由のソフトウェア)
メカニズム:
このソリューションは、Google Play 開発者サービスからオプション モジュールとして配信され、カメラ ストリームに後処理を適用します。HDRNet と呼ばれる高度なリアルタイム画像補正技術を使用します。
Google HDRNet:
このディープ ラーニング モデルは、低解像度で画像を分析して、コンパクトなパラメータ セット(バイラテラル グリッド)を予測します。このグリッドは、GPU 上でフル解像度画像の効率的で空間的に変化する補正をガイドします。このモデルは、暗い場所での画質を明るくして向上させるようにトレーニングされており、顔の視認性に重点を置いています。
プロセス オーケストレーション:
HDRNet モデルとその付随するロジックは、Low Light Boost プロセッサによってオーケストレーションされます。以下が該当します。
-
シーン分析:
カメラのメタデータ(センサー感度、露出時間など)と画像コンテンツを使用して、実際のシーンの明るさを推定するカスタム計算機。この分析により、ブースト レベルが決定されます。 -
HDRNet 処理:
HDRNet モデルを適用してフレームを明るくします。使用されるモデルは、暗いシーンに合わせて調整され、リアルタイム パフォーマンス向けに最適化されています。 -
ブレンド:
元のフレームと HDRNet で処理されたフレームがブレンドされます。適用されるブレンドの量は、シーンの明るさ計算機によって動的に制御され、ブーストされた状態とブーストされていない状態がスムーズに移行します。
メリット:
特定の HAL サポートを必要とせずに、幅広いデバイス(現在は Samsung S22 Ultra、S23 Ultra、S24 Ultra、S25 Ultra、Google Pixel 6 ~ Google Pixel 9 をサポート)で動作します。後処理効果であるため、カメラのフレームレートを維持します。
トレードオフ:
後処理方法であるため、品質はセンサーから配信されるフレームに存在する情報によって制限されます。センサーレベルで極端な暗さのために失われた詳細を復元することはできません。
Low Light Boost は、ハードウェアとソフトウェアの両方のパスを提供することで、Android エコシステム全体で低照度カメラのパフォーマンスを向上させるスケーラブルなソリューションを提供します。デベロッパーは、利用可能な場合は AE モードを優先し、Google Low Light Boost を堅牢なフォールバックとして使用する必要があります。
アプリに Low Light Boost を実装する
次に、LLB の両方の実装方法について説明します。アプリで CameraX と Camera2 のどちらを使用する場合でも、次の実装が可能です。最適な結果を得るには、ステップ 1 とステップ 2 の両方を実装することをおすすめします。
ステップ 1: Low Light Boost AE モード
Android 15 以降を搭載した一部のデバイスで利用可能な LLB AE モードは、特定の自動露出(AE)モードとして機能します。
1. 利用可能かどうかを確認する
まず、カメラ デバイスが LLB AE モードをサポートしているかどうかを確認します。
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector) val isLlbSupported = cameraInfo.isLowLightBoostSupported
2. モードを有効にする
サポートされている場合は、CameraX の CameraControl オブジェクトを使用して LLB AE モードを有効にできます。
// After setting up your camera, use the CameraInfo object to enable LLB AE Mode.
camera = cameraProvider.bindToLifecycle(...)
if (isLlbSupported) {
try {
// The .await() extension suspends the coroutine until the
// ListenableFuture completes. If the operation fails, it throws
// an exception which we catch below.
camera?.cameraControl.enableLowLightBoostAsync(true).await()
} catch (e: IllegalStateException) {
Log.e(TAG, "Failed to enable low light boost: not available on this device or with the current camera configuration", e)
} catch (e: CameraControl.OperationCanceledException) {
Log.e(TAG, "Failed to enable low light boost: camera is closed or value has changed", e)
}
}
3. 状態をモニタリングする
モードをリクエストしたからといって、現在「ブースト」されているとは限りません。システムは、シーンが実際に暗い場合にのみブーストを有効にします。Observer を設定して UI を更新(月のアイコンを表示するなど)するか、拡張関数 asFlow() を使用して Flow に変換できます。
if (isLlbSupported) {
camera?.cameraInfo.lowLightBoostState.asFlow().collectLatest { state ->
// Update UI accordingly
updateMoonIcon(state == LowLightBoostState.ACTIVE)
}
}
Low Light Boost AE モードの詳細なガイドはこちらをご覧ください。
ステップ 2: Google Low Light Boost
ハードウェア AE モードをサポートしていないデバイスの場合、Google Low Light Boost は強力なフォールバックとして機能します。LowLightBoostSession を使用してストリームをインターセプトし、明るくします。
1. 依存関係を追加する
この機能は Google Play 開発者サービスから提供されます。
implementation("com.google.android.gms:play-services-camera-low-light-boost:16.0.1-beta06")
// Add coroutines-play-services to simplify Task APIs
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2")
2. クライアントを初期化する
カメラを起動する前に、LowLightBoostClient を使用して、モジュールがインストールされ、デバイスがサポートされていることを確認します。
val llbClient = LowLightBoost.getClient(context)
// Check support and install if necessary
val isSupported = llbClient.isCameraSupported(cameraId).await()
val isInstalled = llbClient.isModuleInstalled().await()
if (isSupported && !isInstalled) {
// Trigger installation
llbClient.installModule(installCallback).await()
}
3. LLB セッションを作成する
Google LLB は各フレームを処理するため、表示 Surface を LowLightBoostSession に渡す必要があります。これにより、明るくした Surface が返されます。Camera2 アプリの場合は、CaptureRequest.Builder.addTarget() を使用して、結果のサーフェスを追加できます。CameraX の場合、この処理パイプラインは CameraEffect クラスに最適です。このクラスでは、SurfaceProcessor を使用してエフェクトを適用し、SurfaceProvider を使用してプレビューに戻すことができます。このコードをご覧ください。
// With a SurfaceOutput from SurfaceProcessor.onSurfaceOutput() and a
// SurfaceRequest from Preview.SurfaceProvider.onSurfaceRequested(),
// create a LLB Session.
suspend fun createLlbSession(surfaceRequest: SurfaceRequest, outputSurfaceForLlb: Surface) {
// 1. Create the LLB Session configuration
val options = LowLightBoostOptions(
outputSurfaceForLlb,
cameraId,
surfaceRequest.resolution.width,
surfaceRequest.resolution.height,
true // Start enabled
)
// 2. Create the session.
val llbSession = llbClient.createSession(options, callback).await()
// 3. Get the surface to use.
val llbInputSurface = llbSession.getCameraSurface()
// 4. Provide the surface to the CameraX Preview UseCase.
surfaceRequest.provideSurface(llbInputSurface, executor, resultListener)
// 5. Set the scene detector callback to monitor how much boost is being applied.
val onSceneBrightnessChanged = object : SceneDetectorCallback {
override fun onSceneBrightnessChanged(
session: LowLightBoostSession,
boostStrength: Float
) {
// Monitor the boostStrength from 0 (no boosting) to 1 (maximum boosting)
}
}
llbSession.setSceneDetectorCallback(onSceneBrightnessChanged, null)
}
4. メタデータを渡す
アルゴリズムが機能するには、カメラの自動露出状態を分析する必要があります。キャプチャ結果を LLB セッションに渡す必要があります。CameraX では、Camera2Interop.Extender.setSessionCaptureCallback() を使用して Preview.Builder を拡張することで、これを行うことができます。
Camera2Interop.Extender(previewBuilder).setSessionCaptureCallback(
object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(
session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult
) {
super.onCaptureCompleted(session, request, result)
llbSession?.processCaptureResult(result)
}
}
)
クライアントとセッションの詳細な実装手順については、 Google Low Light Boost ガイドをご覧ください。
次のステップ
これらの 2 つのオプションを実装することで、照明条件に関係なく、ユーザーがはっきりと見ることができ、確実にスキャンして、効果的に操作できるようにします。
完全な本番環境対応のコードベースでこれらの機能が実際に動作していることを確認するには、GitHub の Jetpack Camera App をご覧ください。LLB AE モードとGoogle LLBの両方を実装しているため、独自の統合の参考になります。
続きを読む
-
プロダクト ニュース
Android 17 がベータ版 4 に到達しました。これは、このリリース サイクルの最後のベータ版であり、アプリの互換性とプラットフォームの安定性にとって重要なマイルストーンです。
Daniel Galpin • 所要時間 4 分
-
2026 年 4 月 15 日2026 年 4 月 15 日
プロダクト ニュース
Google Play の安全性と信頼性を可能な限り高く保つため。本日、ユーザーのプライバシーを強化し、不正行為からビジネスを保護するための新しいポリシーの更新とアカウント移行機能についてお知らせします。
Bennet Manuel • 所要時間 3 分
-
プロダクト ニュース
Android Emulator を使用すると、マルチデバイス インタラクションのテストがこれまで以上に簡単になります。
Steven Jenkins • 所要時間 2 分
メールを受け取る
Android 開発に関する最新の分析情報を毎週メールでお届けします。