幻境相机 Mirage Camera

幻境相机 Mirage Camera

一款免费 · 离线 · 隐私优先 的 Android 电影感相机。

不用购买专业设备,也能拍出电影质感。

复制代码
免费 · 离线 · 隐私优先 · 无账号 · 无社区 · 无强制联网
Android 11+ (API 30+) · 纯 Kotlin · Jetpack Compose · CameraX

https://github.com/lfl171/Mirage-Camera.git

这是什么

一个真实可运行的 Android 相机 App ------ 不是设计稿,不是原型。

启动即进入取景器,所见即所得地预览 15 套电影调色模板,按下快门得到

「原图 + 成片」两张照片。

电影感从哪来? 不是简单套一层颜色,而是完整的处理链:

复制代码
FilmPreset(模板定义)
    ├── AutoParams    → 回写相机(拍摄阶段就设定曝光/白平衡)
    ├── ColorGrade    → 阴影/高光分区染色   ┐
    ├── ToneParams    → 对比/饱和/颗粒/暗角 ├→ 烘焙为 3D LUT
    ├── AiStrategy    → 人物肤色保护策略     ┘
    └── LUT           → 32³ 色彩查找表
             ↓
    CapabilityResolver(按设备能力自动降级)
             ↓
    EffectivePreset
             ↓
    RendererSelector
        ├── GPU LUT Renderer
        └── CPU LUT Renderer(采样同一张 LUT)
             ↓
    颗粒 / 暗角后处理
             ↓
        成片 JPEG

核心特性

🎬 15 套电影模板

分类 模板
城市 🌆 赛博霓虹 · 🏮 港风夜色 · 🏢 水泥极简
夕阳 🌅 黄金日落 · 🎞 日落记忆
电影 🎬 蓝橙电影 · 🌃 午夜城市 · 🌲 森林电影 · ❄ 北境冷调
胶片 🎞 胶片 35mm · 📷 徕卡街拍 · 🌧 雨夜黑白
人像 👤 梦幻人像
风格 🌇 动漫夕阳 · 🦇 暗黑英雄

每套模板都有量化质量评分 (高光保护 / 暗部恢复 / 肤色保护 /

噪声水平 / 电影感评分),不是凭感觉调色。

📷 五种拍摄模式(会真正改变参数)

模式 曝光 变焦 推荐模板
自动 0 --- 原片直出
电影 −0.3 EV 1× 蓝橙电影
人像 +0.3 EV 2× 梦幻人像
夜景 +0.7 EV 1× 午夜城市
专业 手动 --- 不套用

🔍 系统兼容中心

基于 Camera2 Hardware Level 逐项探测设备真实能力,

前后摄独立探测(同一台设备两颗摄像头的等级常常不同)。

复制代码
① 后置摄像头 · 当前使用    LEVEL_3   7 / 12 能力可用
② 前置摄像头(未在使用)    LEVEL_3   6 / 12
③ Mirage 能力
④ 兼容性结论

设计立场:硬件等级只是底层数据,不等于各项能力的开关。

我们逐项判定 ,缺失时自动降级并明确告知 ------

不会出现「LIMITED = 低端机 = 不支持 X」这种粗暴结论。

🎯 拍摄指导

基于当前曝光 / ISO / 快门 / 变焦的离线规则引擎,实时提示

「高光过曝风险」「建议开启 HDR」等,全部本地计算。

📄 照片信息页

每张成片都写入完整 EXIF 元数据,并提供独立的

「这张照片是怎么拍出来的」页面。

🔒 隐私承诺(技术保证,不是口号)

  • Manifest 中刻意没有 INTERNET 权限 ------ 从系统层面无法联网
  • 无账号、无上传、无社区、无追踪
  • 所有调色、EXIF 写入均在本机完成
  • 照片只保存在 Pictures/MirageCamera/

技术栈

项 版本
语言 Kotlin 2.0.20
UI Jetpack Compose (BOM 2024.09.03)
相机 CameraX 1.3.4
构建 AGP 8.5.2 / Gradle 8.8 / JDK 17
SDK minSdk 30 (Android 11) · targetSdk 35

没有引入任何网络库 ------ 这是刻意的架构决策。


快速开始

bash 复制代码
git clone https://github.com/lfl171/Mirage-Camera.git
cd Mirage-Camera

用 Android Studio 打开项目目录,直接运行即可。

或命令行构建:

bash 复制代码
./gradlew assembleDebug     # 调试包
./gradlew assembleRelease   # 正式包(已配置签名)

local.properties 需要指向你的 Android SDK:

复制代码
sdk.dir=/path/to/Android/Sdk

项目结构

复制代码
app/src/main/java/com/mirage/camera/
├── MainActivity.kt
├── camera/                      # 相机与渲染
│   ├── CameraEngine.kt          # CameraX 封装(预览/对焦/变焦/拍照)
│   ├── FilmProcessor.kt         # 成片生成管线
│   ├── FilmRenderer.kt          # FilmRenderer 抽象 + GPU/CPU 实现 + 选择器
│   ├── GpuLut.kt                # 3D LUT 烘焙(LutBaker)+ 能力检测
│   ├── CapabilityProbe.kt       # Camera2 能力逐项探测(前后摄独立)
│   ├── CapabilityResolver.kt    # 按能力自动降级
│   ├── ConsistencyTest.kt       # 渲染一致性 / 几何 / 强度回归测试
│   ├── MirageStore.kt           # MediaStore 存取 + EXIF 写入
│   └── PreviewRenderer.kt       # 预览渲染抽象 + PreviewTransform
├── ui/
│   ├── components/
│   │   ├── FilmPreset.kt        # 15 套模板定义 + 质量评分
│   │   ├── PresetRenderer.kt    # 预览渲染
│   │   ├── Scenes.kt            # 程序化场景(模板缩略图)
│   │   ├── SceneAssistant.kt    # 拍摄指导规则引擎
│   │   └── Color.kt
│   └── screens/                 # 全部页面
└── ui/theme/

工程实践(本项目踩过的坑)

这些是真实踩过的坑,都写进了代码注释,避免后人重蹈:

1. 移动端像素循环内零对象分配

成片处理曾耗时 41 秒 (真机 2592×1944)。

根因是每次 LUT 采样返回 Triple<Int,Int,Int> ------

每像素分配 8 个对象,150 万像素 = 1200 万次分配,GC 压垮了计算。

改为纯整数、无分配后:694 ms(提速 59 倍)。

分配比算术慢一个数量级。

2. 同一处理只能出现一次

接线 LUT 后,FilmProcessor.drawGrade() 和 LutBaker 里

各做了一遍分区染色,导致调色被叠加两次。

引入新的处理层时,必须逐项核对哪些处理已经在里面了。

3. 预览 LUT 不能让 shader 自己猜几何

PreviewTransform 显式承载 rotation / scale / crop / mirror,

shader 只负责按给定 UV 采样 ------ 避免「调色一样但画面位置不一样」。

4. Canvas(Bitmap) 永远是软件 Canvas

AGSL(RuntimeShader)在软件 Canvas 上无法执行,必然抛

Software rendering doesn't support RuntimeShader。

GPU 路径需要硬件加速的渲染目标。

5. 模拟器验证不了性能与 GPU

模拟器像素少 4 倍,掩盖了 59 倍的性能差距;

模拟器无硬件 GPU,曾让我把实现错误误判为设备限制。

模拟器能验证逻辑正确性,但验证不了性能和 GPU 真实行为。


内置验证工具

设置 → 开发诊断 → LUT 一致性测试(仅 debug 包显示)

一次跑完并输出可复制报告:

测试 内容 当前结果
LUT 采样 vs 直算 三维插值寻址是否正确 12 / 12(ΔE 0.83--1.50)
强度回归 强度滑杆是否真正生效 4 / 4
几何一致性 CENTER_CROP / 旋转 / 镜像 UV 映射 7 / 7
GPU vs CPU 降级是否改变颜色 待 GPU 路径实现

报告同时输出到 Logcat,可直接取回:

bash 复制代码
adb logcat -s MirageVerify:I

已知限制

项 状态 说明
GPU 实时调色 ❌ 未启用 当前走 CPU。预览显示「兼容影像模式」提示。成片颜色不受影响(CPU 与 GPU 用同一张 LUT),仅速度略慢(真机 694 ms)
夜景降噪 ❌ 未实现 提亮暗部后噪点比预期明显。设计里有承诺,实现待补
电影模式弱光偏暗 ⚠️ −0.3 EV 压高光在弱光下会发闷,建议加环境光条件判断
观感验证 ⚠️ 仅在室内弱光环境测过,夕阳/街拍/人像等目标场景的实际效果需真机实拍判断

已验证环境

Lenovo TB331FC · Android 15 (API 35) · arm64 · Adreno GPU

  • 安装运行 ✅ · 相机预览拍照 ✅ · 成片 694 ms ✅
  • 双摄能力探测 ✅(双摄 LEVEL_3,均支持 RAW)
  • 15 套模板全部可用 ✅ · 0 崩溃 ✅
  • 编译零警告 ✅

关于密钥

仓库中的 debug.keystore 与 mirage-release.jks 是刻意保留 的,

以便任何人 clone 后可以直接 assembleRelease 复现出同样的签名包。

⚠️ 生产项目请勿这样做。 正式密钥必须私有保管 ------

泄漏意味着他人可以冒充你的应用发布更新。

若你基于本项目发布自己的应用,请务必替换为自己的密钥。


设计文档

完整的设计决策与迭代记录在 ../mirage-camera/ 目录(共 12 份):

  • DESIGN-SYSTEM-v1.2 ... v7.0 --- UI 体系到预览管线的设计演进
  • VERIFICATION-v8.0 / v9.0 / v10.0 --- 验证报告(含错误结论的更正)
  • SHOOT-TEST-v11.0 --- 真机实拍观感验证

值得一读的是 VERIFICATION-v9.0 → v10.0 的更正:

我曾把 GPU 实现错误误判为「设备不支持」,真机验证后推翻了这个结论。


许可

本项目为学习与个人使用而创建。


一句话总结

不用购买专业设备,也能拍出电影质感。

相关推荐
Lancker7 小时前
没有 Mac 也能上架 iOS:GitHub Actions 全自动构建 + 签名 + TestFlight 送审实录
macos·ios·github
小弥儿7 小时前
GitHub今日热榜 | 2026-10-09:PS5 移植登顶,AI 创作工具占三席
人工智能·学习·开源·github
怕浪猫8 小时前
Agent 的记忆系统怎么设计?面试官想听的是这个
算法·面试·github
miofly9 小时前
GitHub 日榜趋势速报 | 2026-10-10
开源·github
高频因子挖掘机9 小时前
股票历史数据缺了一天怎么发现?用 Pandas 检查交易日期连续性
后端·github·api
高频因子挖掘机9 小时前
量化回测最危险的错误,不是程序报错,而是数据错了却正常运行
后端·github·api
m4Rk_1 天前
【论文阅读】Agent 记忆机制(94):MemGen——在推理过程中动态生成并织入潜在记忆
论文阅读·人工智能·学习·开源·github
wflynn1 天前
GitHub 今日推荐|ts-rust:把微软 TypeScript-Go 编译器逐行移植成 Rust 实现
rust·typescript·开源·github·compiler·tsc
明月_清风1 天前
面对陌生的 GitHub 项目无从下手?这 4 个网站帮你快速读懂源码
前端·后端·github
SL_staff1 天前
Excel如何自动升级为可搜索的知识节点:JVS文档平台的语义解析实践
开源·github·全栈