幻境相机 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 实现错误误判为「设备不支持」,真机验证后推翻了这个结论。
许可
本项目为学习与个人使用而创建。
一句话总结
不用购买专业设备,也能拍出电影质感。