たくさんの自由帳

JetpackCompose で HDR の眩しい画面を作ろう

投稿日 : | 0 日前

文字数(だいたい) : 3272

どうもこんばんわ。DLSiteでためしにTLもの買ったら送られてくるメールが180度変わった話する?しません。

じゃあGoogle Store 表参道行ってきたのでその話を、まあ写真取り損ねてるしオープンしてからしばらくたった後ですが。
場所はGalaxy Harajukuの近く。偶然なの?

GoogleStore表参道

HiLight体験コーナー。電話をかけると隣のPixelHiLight(カメラのフラッシュにあるやつ)が光る。

Pixel11HiLight実演

なおこの光るやつ、すでに内部のAPIが解析された?らしい。まあ案の定サードパーティー開発者には解放されてなくShizukuを使って代わりにAPIを叩く必要があるらしい。
昔のAndroid端末にはLED インジゲーターがあったので、通知が来たときに光らせるためのNotificationCompat.Builder#setLightsがあったわけですがこれを復活させる気は無いの?

Watchとかは紐で括りつけられてなかった、まあデモ機っぽいからいいのかな
あとは交換するバンドも展示されてました。確かに高いだけあって物がよさそう感。高いからさすがに買わないけど、、

PixelWatch展示

もちろん(?)二階に上がることもできました。AI体験コーナーとお土産コーナーがありました。写真は取り損ねました。
あばたー?が作れるらしい。

お土産コーナーも撮り損ねたわけですが、Google Chrome タブで分けられるクリアファイルとか水筒とか醤油入れ?とかステッカーとかボールペンとかありました。
今回はGoogle Chrome恐竜ステッカーを買ってみた。2枚買って780円だったので1枚300円ちょいだと思います。ドロイド君グッズも置いてほしいです。

買ってきたもの

なんか高々シールを二枚しか買ってないのにオシャレな手提げ袋をもらった。このサイズと色は日本限定らしい!
中にケーブルをまとめられるペーパークラフトみたいなのも入れてくれた!

ちなみに支払いは(ほかのスマホ購入とかは知らないけど)近くにいたおねーさんに言ってその場で支払いできた。というかレジがない!
クレカPayPayとあと何かで払えるって言ってたはず。おねーさんがPixelと決済するスマホみたいなのを操作しててその場で支払えた。

まあシールにしてはちょっと高いかな~とか思いつつミスって机の下に落っことしたときに気付いた。このシール蓄光じゃね!?
電気消してみた。蓄光だった!!暗がりで光るChrome の恐竜。ほかのシールもそうなのかな、おねーさんなにも言ってなかったはず。

蓄光シールだった

本題

Jetpack Compose Bom 2026.08からHDRの色が使えるようになったぽいので試します。確かに眩しい!!
BT.2020 (Rec.2020)のカラースペースが使える?)

HDRの色を描画したJetpackComposeでできた画面

ChromeHDR対応ディスプレイの組み合わせなら、↑のUltraHDRが眩しい写真になってるはず。

HDR 入門

詳しくは前書いた記事に譲ります。カラースペースとかガンマカーブとか!

環境

HDRが表示できるディスプレイでAndroid 13以上ならいいと思います。エミュレーターでできるかは知らない。
冒頭に貼った写真がUltraHDRで、これがAndroid Chromeで眩しく表示されたら多分HDRディスプレイを搭載しているはずです。

なまえあたい
AndroidStudioAndroid Studio Quail 3 2026.1.3 Patch 1
端末Xperia 1 VIII / Pixel 10 Pro Fold

分からなかったこと

Modifier.background()の時は眩しかったけど、Text()colorIcon()tintには適用されてない気がする。私が何か間違えているかもしれない。

Activity で HDR を有効にする

UltraHDRを表示するときと同じようにActivityInfo.COLOR_MODE_HDRを呼び出す

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        // 多分 UltraHDR を表示するのと同じ要領でこれが必要だと思う
        window.colorMode = ActivityInfo.COLOR_MODE_HDR
    }
}

Color() を作るときに colorSpaces を指定する

ColorSpaces.Bt2020HlgColorSpaces.Bt2020Pqがあります。
名前通りカラースペースはBT.2020 (Rec.2020)で、それぞれガンマカーブがHLGPQ (ST2084)だと思います。

Color(red = 1f, green = 0f, blue = 0f, alpha = 1f, colorSpace = ColorSpaces.Bt2020Hlg)

コード例

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        // 多分 UltraHDR を表示するのと同じ要領でこれが必要だと思う
        window.colorMode = ActivityInfo.COLOR_MODE_HDR

        setContent {
            JetpackComposeHdrColorTheme {
                MainScreen()
            }
        }
    }
}

@Composable
private fun MainScreen() {
    Scaffold { innerPadding ->
        Column(
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            MessageCard(text = "SDR の色", colorSpace = ColorSpaces.Srgb) // sRGB が動画で言うところの Rec.709 (BT.709) にあたる
            MessageCard(text = "HDR の色", colorSpace = ColorSpaces.Bt2020Hlg)
            MessageCard(text = "眩しい広告!", colorSpace = ColorSpaces.Bt2020Hlg)

            Icon(
                painter = painterResource(R.drawable.ic_launcher_foreground),
                contentDescription = null,
                tint = Color(red = 1f, green = 0f, blue = 0f, alpha = 1f, colorSpace = ColorSpaces.Bt2020Hlg)
            )

            Box(
                modifier = Modifier
                    .size(200.dp)
                    .background(
                        Brush.horizontalGradient(
                            listOf(
                                Color(red = 1f, green = 0f, blue = 0f, alpha = 1f, colorSpace = ColorSpaces.Bt2020Hlg),
                                Color(red = 0f, green = 1f, blue = 0f, alpha = 1f, colorSpace = ColorSpaces.Bt2020Hlg),
                                Color(red = 0f, green = 0f, blue = 1f, alpha = 1f, colorSpace = ColorSpaces.Bt2020Hlg)
                            )
                        )
                    )
            )
        }
    }
}

@Composable
private fun MessageCard(
    modifier: Modifier = Modifier,
    text: String,
    colorSpace: ColorSpace
) {
    Box(modifier = modifier.background(Color(red = 1f, green = 1f, blue = 1f, alpha = 1f, colorSpace = colorSpace))) {
        Text(
            modifier = Modifier.padding(10.dp),
            text = text,
            fontSize = 50.sp,
            color = Color(red = 1f, green = 0f, blue = 0f, alpha = 1f, colorSpace = colorSpace)
        )
    }
}

眩しい画面が出来た!

手元だとなぜかText()とかは眩しくなってない気がします・・

冒頭の再掲

おわりに

いままでHDRの色を表示するにはOpenGL ESを書かないといけなかった気がして?いい時代になりました!!!