RORK LABEN
VERIFY — Android の開発者認証が2026年9月に完全義務化されます。Android 17 以降の端末では認証が OS 側に実装され、認証を経ていないアプリは新規インストールが OS レベルでブロックされうる構造ですREVIEW — 9月から、App Store への新規申請・アップデート申請と、代替配信向けの notarization で回答の提出が必須になりますSDK — iOS 27 と Xcode 27 は9月に正式リリース見込みです。提出アプリへの iOS 27 SDK ビルド必須化は2027年春の予定で、こちらは1年近い猶予がありますTIMELINE — Rork の $15M シードと Paperline 買収は2026年4月9日の発表です。直近のニュースではないため、記事で扱う際は時系列を明確に区別する必要がありますMAX — Rork Max は native Swift を出力し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessage が対象です。標準の Rork は React Native(Expo)でクロスプラットフォームのアプリを生成しますEXPORT — 自動の Publish が失敗しても、GitHub へ同期して React Native のソース一式を無料でエクスポートし、手動で提出まで進められますVERIFY — Android の開発者認証が2026年9月に完全義務化されます。Android 17 以降の端末では認証が OS 側に実装され、認証を経ていないアプリは新規インストールが OS レベルでブロックされうる構造ですREVIEW — 9月から、App Store への新規申請・アップデート申請と、代替配信向けの notarization で回答の提出が必須になりますSDK — iOS 27 と Xcode 27 は9月に正式リリース見込みです。提出アプリへの iOS 27 SDK ビルド必須化は2027年春の予定で、こちらは1年近い猶予がありますTIMELINE — Rork の $15M シードと Paperline 買収は2026年4月9日の発表です。直近のニュースではないため、記事で扱う際は時系列を明確に区別する必要がありますMAX — Rork Max は native Swift を出力し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessage が対象です。標準の Rork は React Native(Expo)でクロスプラットフォームのアプリを生成しますEXPORT — 自動の Publish が失敗しても、GitHub へ同期して React Native のソース一式を無料でエクスポートし、手動で提出まで進められます
記事一覧/アプリ開発
アプリ開発/2026-08-06上級

壁紙の上の文字が読めるかを、端末ではなく取り込み時に決める — 判定指標を4つ測り比べた記録

壁紙の上に置くステータスバーや見出しが読めるかを、端末での画像解析ではなく取り込み時のメタデータで決める設計です。240枚のコーパスで判定指標を4つ実測し、縮小画像での判定が何と一致するのかまで記録しました。

Rork527Expo158React Native219画像処理4アクセシビリティ5コンテンツパイプライン

プレミアム記事

夜空の壁紙を開いたとき、画面の上端にうっすらとした黒い帯が乗っているのが見えました。星が数個あるだけの、ほとんど真っ黒な絵です。白い時計は帯がなくても十分に読めます。それでも黒帯は律儀にかかっていました。

個人開発で壁紙アプリを運用しており、画像の上に時計とタイトルを重ねる画面があります。可読性を守るために、上端へ rgba(0,0,0,0.35) のグラデーションを一律で敷いていました。安全側に倒した実装です。

安全側であることと、正しいことは違います。夜空の絵は、その黒帯のぶんだけ暗く見えていました。逆に、淡いパステル調の絵では 0.35 では足りず、白文字が滲んで見える画面もありました。一律の値は、両側で外していたわけです。

では画像ごとに決めればよいはずです。問題は「何をもって読めると判定するか」で、ここが思っていたより深い穴でした。手元で 240 枚のコーパスを作り、判定指標を4つ順番に試した記録を残します。結論から言えば、最後に採用した方式では 240 枚中 189 枚でスクリムそのものが不要になりました。

判定を端末から取り込み時へ移す

最初に決めたのは、判定をどこで走らせるかです。

端末側で画像を解析する案は、すぐに落としました。壁紙は数千枚あり、スクロール中に次々と表示されます。表示のたびにピクセルを読むのは、描画予算を最も使いたくない場所で使う判断です。しかも同じ画像に対して端末ごとに違う答えが出る余地が残ります。

採ったのは、取り込み時に一度だけ計算し、結果を数値としてカタログへ書き込む形です。アプリ側は画像を一切解析しません。JSON に入っている stylescrim を読むだけになります。

判定の置き場所表示時のコスト結果の一貫性やり直しの手間
端末(表示のたび)毎回かかる端末・OS で揺れる不要
端末(初回のみキャッシュ)初回のみキャッシュ破棄で揺れる不要
取り込み時(採用)ゼロ完全に固定再計算とデプロイが必要

やり直しの手間だけが増えます。判定ロジックを変えたら全アセットを再計算し、カタログを配り直すことになります。数千枚を一括処理できる速度を確保しておけば、この手間は許容範囲に収まると考えました。実際の処理時間は後半で測っています。

明るさの平均は、色で外れる

最初に書いたのは、思いつく限り最も素朴な判定でした。UI が乗る上端 12% の帯を切り出し、RGB の単純平均を取り、0.5 未満なら白文字にする。

これを 240 枚に流し、フル解像度で相対輝度の 95 パーセンタイルを取った結果と突き合わせました。一致は 120 枚でした。

240 枚中 120 枚。コインを投げるのと変わりません。

食い違いの内訳を見ると、原因ははっきりしていました。緑が支配的な葉の画像で 40 枚、夕景で 40 枚、中間調のテクスチャで 40 枚。いずれも (R+G+B)/3 が、人の目の感度と対応していない領域です。

WCAG が定める相対輝度は、sRGB 値を線形化したうえで緑に 0.7152、赤に 0.2126、青に 0.0722 の重みを掛けます。緑の寄与は青の 10 倍近くあります。単純平均はこの差を潰してしまいます。

import numpy as np
 
def relative_luminance(rgb: np.ndarray) -> np.ndarray:
    """sRGB(uint8 または float) -> WCAG 2.x 相対輝度。
    単純平均ではなく、必ず線形化してから重み付けします。"""
    c = rgb.astype(np.float64) / 255.0
    lin = np.where(c <= 0.04045, c / 12.92, ((c + 0.055) / 1.055) ** 2.4)
    return 0.2126 * lin[..., 0] + 0.7152 * lin[..., 1] + 0.0722 * lin[..., 2]

この関数に差し替えて、平均相対輝度で同じ判定をやり直しました。一致は 200 枚に上がりました。夕景と中間調テクスチャの誤りは、80 枚まるごと消えています。

残ったのは葉の画像 40 枚です。こちらは色の問題ではありませんでした。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
明るさの平均・分位点・窓平均という3系統の判定指標が、240枚のうち何枚で食い違ったかの実測値
縮小画像で判定すると精度が落ちるという前提が、実際には何を計算していたのかの測定結果
一律スクリムを配る実装が不要に暗くしていた枚数と、文字色切り替えへ置き換えたときの削減幅
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-07-14
壁紙を長押しして、プレビューと保存メニューを出す — Rork の Expo アプリで context menu を組む
壁紙ギャラリーのカードを長押ししても何も起きない。iOS利用者はプレビュー付きのメニューを期待します。Pressableだけでは届かない理由から、zeegoでのネイティブcontext menu実装、スクロールとの競合解消、保存・共有アクション、Android向けの自前フォールバックまで、動くコードでまとめます。
アプリ開発2026-07-07
高さの異なる画像を2列で美しく並べる—Rork の Expo アプリで壁紙ギャラリーを段組みにする
縦横比のばらつく画像を numColumns では美しく並べられない理由から、列の高さを見て振り分ける段組みアルゴリズム、FlashList の masonry での仮想化、依存を増やさない実装まで、壁紙ギャラリーを実コードで組みます。
アプリ開発2026-07-05
ワンタイムコードの入力欄をExpoで作る — SMS自動入力とセグメント表示を両立させる
6桁の確認コードを入れる画面は、見た目こそ単純ですが、SMSの自動入力・貼り付け・1文字ずつの削除まで含めると意外と作り込みが必要です。iOSとAndroidの自動入力を最初に押さえ、単一のTextInputで崩れにくいセグメント表示を組む実装をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →