AI 一键图片优化

文档类型:产品 + 技术方案 + 参数标准
针对能力:AI 一键优化(AI One-Click Image Optimization)
最后更新:2026-07-08
维护者:PM Agent(产品定义)+ RD Agent(技术实现)+ CR Agent(合规审查)

历史合并说明:本文档由 AI_ONE_CLICK_OPTIMIZATION_PROPOSAL.mdAI_OPTIMIZE_PARAMETER_STANDARD.md 合并而成。参数预设以 AI_OPTIMIZE_PARAMETER_STANDARD.md 为准,已合并重复内容。


1. 核心结论

AI 一键优化是新路线下最值得投入的 P0 能力之一:

推荐策略: - MVP(Phase 1):本地快速优化为主,覆盖 80% 常见场景,端到端 < 1s - Phase 2:引入远程视觉模型做「智能推荐」,处理复杂/模糊场景,首次使用需用户授权 - Phase 3:对话式微调、批量优化、个性化学习

不做的事情: - 不做「AI 换脸/重绘」等生成式修改(超出美颜/滤镜/调节范围) - 不做「自动保存覆盖原图」(必须是非破坏性编辑) - 不做「无授权云端处理」(遵循新隐私红线)


2. 产品定义

2.1 一句话描述

用户一键触发,系统自动识别照片场景并应用最优美颜 + 滤镜 + 调节参数,生成更好看的新照片。

2.2 解决什么问题

用户痛点 当前做法 AI 一键优化后
不知道参数怎么调 手动滑块试错 一键给出推荐,可在此基础上微调
修图步骤繁琐 打开编辑 → 调美颜 → 调滤镜 → 保存 一键完成,直接进入对比/保存
不同场景参数差异大 凭感觉调 基于场景(人像/风景/美食/文档)自动匹配
批量修图累 一张张手动调 选中多图后批量应用同一套优化逻辑

2.3 入口与交互流程

入口 优先级 说明
媒体查看器工具栏 P0 查看单图时顶部工具栏「AI 优化」按钮,最自然的一键入口
编辑器内「AI 一键优化」 P0 编辑页顶部/BeautySelector 面板中的「AI 优化」按钮
相册多选批量操作 P1 长按多选后底部操作栏「AI 优化」
AI 对话命令 P1 “帮我优化这张照片”,结果以图片消息返回
IM 远程控制 P2 实验线,与 IM 远程控制同步推进

2.4 单图优化流程

用户点击「AI 优化」
    ↓
系统显示「正在分析照片…」(< 500ms 本地路径可跳过 loading)
    ↓
本地场景识别(人脸/场景标签/光线)
    ↓
匹配预设配方(本地规则引擎)
    ↓
生成推荐卡片:
  ┌─────────────────────────────┐
  │  🌇 检测到风景照片            │
  │  已提升通透度、增强天空色彩    │
  │  [应用]  [微调]              │
  └─────────────────────────────┘
    ↓
用户选择:
  - 应用 → 直接保存为新文件,进入对比模式
  - 微调 → 进入编辑器,参数已预填,用户可继续调整
  - 换一换 → 调用远程视觉模型重新推荐(需授权)

3. 技术方案

3.1 总体架构:本地优先 + 云端增强

┌─────────────────────────────────────────────────────────────┐
│                      AiOptimizeCapability                    │
│  输入:imageUri + mode(fast|smart) + source                   │
│  输出:OptimizeRecommendation(场景 + 配方 + 说明)            │
└───────────────────────────┬─────────────────────────────────┘
                            │
        ┌───────────────────┴───────────────────┐
        ▼                                       ▼
┌───────────────┐                       ┌───────────────────┐
│ FastOptimize  │  默认路径,< 500ms     │ SmartOptimize     │  增强路径,1-3s
│ Engine(本地) │  无需网络              │ Engine(远程)    │  需用户授权
└───────┬───────┘                       └─────────┬─────────┘
        │                                         │
        ▼                                         ▼
┌───────────────┐                       ┌───────────────────┐
│ SceneAnalyzer │                       │ VisionLlmClient   │
│ - ML Kit 图像标签 │                   │ - OpenAI 兼容 API │
│ - 人脸检测      │                       │ - GPT-4o / Qwen-VL│
│ - 光线/色彩启发式│                      │ - 压缩图 base64   │
└───────┬───────┘                       └─────────┬─────────┘
        │                                         │
        ▼                                         ▼
┌───────────────┐                       ┌───────────────────┐
│ PresetRepo    │                       │ ResponseParser    │
│ 本地 JSON 预设库│                       │ 解析推荐参数        │
└───────────────┘                       └───────────────────┘

3.2 Fast 路径(本地,默认)

为什么优先本地: - 符合新隐私红线「敏感数据优先本地」 - 速度最快,用户体验最好 - 不依赖网络,离线可用 - 80% 常见场景可用规则覆盖

场景识别输入

信号 来源 用途
人脸数量/位置/大小 MediaPipe / ML Kit Face Detection 判断人像/自拍/合影
图像标签 Top-K ML Kit Image Labeling 判断风景/食物/文档/动物/建筑等
EXIF 信息 MetadataExtractor 判断白天/夜晚/逆光、焦距
直方图/亮度统计 GPU 管线采样 判断过曝/欠曝/低对比度
色彩分布 简单色彩直方图 判断偏暖/偏冷/饱和度

规则引擎示例

when {
    faceCount >= 2 && faceRatio > 0.1 -> "group_portrait"
    faceCount == 1 && faceRatio > 0.3 -> "selfie"
    faceCount == 1 && faceRatio < 0.3 -> "portrait"
    labels.containsAny("Food", "Meal", "Dish") -> "food"
    labels.containsAny("Sky", "Mountain", "Sea", "Tree") -> "landscape"
    labels.containsAny("Document", "Text") -> "document"
    brightness < 40 -> "low_light"
    else -> "general"
}

3.3 Smart 路径(远程,增强)

触发条件: - 用户主动点击「换一换 / 智能推荐」 - Fast 路径置信度低于阈值(如 < 0.6) - 用户设置了「智能推荐优先」

实现方式

  1. 图像编码:将原图缩放至 512px 长边,JPEG 质量 80,转 base64
  2. 模型选择:通过 OpenAI 兼容 API 调用视觉模型
    • 推荐:GPT-4o-mini(成本可控)或 Qwen-VL-Max
    • 避免依赖 DeepSeek(当前公开版本无 vision 能力)
  3. Prompt 设计
你是一位手机修图专家。请分析这张图片,并返回 JSON 推荐修图参数。

输出格式:
{
  "scene": "场景英文名",
  "scene_label_zh": "中文场景名",
  "confidence": 0.0-1.0,
  "recipe": {
    "beauty": {"smooth":0-100, "whiten":0-100, "slimFace":-50~50, "bigEye":0-100, "lipColor":0-100, "blush":0-100, "enabled":true|false},
    "filter": "none|film_gold|vivid|natural|warm|cool|leica_classic|...",
    "adjustment": {"brightness":-50~50, "contrast":-50~50, "saturation":-50~50, "warmth":-50~50}
  },
  "explanation": "一句话说明做了什么优化"
}
  1. 隐私合规
    • 首次调用前弹窗告知「将上传压缩图片至云端模型,是否允许?」
    • 设置中提供「允许云端 AI 优化」开关
    • 不在云端存储用户图片

3.4 本地 Qwen3.5-2B 多模态作为离线 fallback

项目已有的 TagGenerationPipeline Pass 3 使用 Qwen3.5-2B 做图像理解。可探索复用该路径:

当前限制: - 2B 模型输出 JSON 稳定性有限 - 推理速度约 1-3s(取决于设备) - 功耗/发热较高

建议:不作为默认路径,仅作为无网络且用户未禁用云端时的降级提示:“当前无法使用智能推荐,已应用本地优化”。


4. 参数标准与预设规范

4.1 参数体系选择

不存在强制统一的二进制标准,但移动端修图领域有两套事实上的「用户心智」:

体系 代表产品 特点 适用参数
Apple Photos 体系 iOS 相册、VSCO、Lightroom Mobile -100 ~ +1000 ~ 100 为中心对称滑杆,0 为「无效果」 曝光、亮度、对比度、饱和度、色温、色调
国产美颜体系 小米相机、美图秀秀、轻颜相机 0 ~ 100 表示强度,50 或 0 为「自然/关闭」 磨皮、美白、瘦脸、大眼、唇色、腮红

PicMe 的选择: - 美颜参数:对齐国产美颜体系,0 ~ 100 为强度,0 为关闭;瘦脸 -50 ~ +50,负值丰脸。 - 调色参数:尽量对齐 Apple Photos 用户心智,但保留当前内部映射: - brightness / exposure / tint-100 ~ +1000 为原图。 - contrast / saturation0 ~ 20050/100 为原图(与 Apple 的 -100 ~ +100 等价,只是零点偏移)。 - temperature2000K ~ 8000K5000K 为原图(与 Apple Warmth 方向一致,但使用 Kelvin 标度)。

这样选择的原因是:底层大美丽 Shader 已使用 0~4 对比度、0~2 饱和度映射,当前 0~200 UI 范围可直接整除映射,改动最小;同时用户在滑杆上看到的「50 = 原图对比度、100 = 原图饱和度」与常见修图 App 的百分比概念接近。

4.2 参数语义、范围与滑杆映射

美颜(Beauty)

参数 UI 范围 默认值 语义 引擎归一化 参考来源
smoothing 磨皮 0 ~ 100 0 0=关闭,100=最强磨皮 smoothing / 1000.0 ~ 1.0 小米/美图
whitening 美白 0 ~ 100 0 0=关闭,100=最强美白 whitening / 1000.0 ~ 1.0 小米/美图
slimFace 瘦脸 -50 ~ +50 0 负值=丰脸,正值=瘦脸 slimFace / 50 * 1.35-1.0 ~ 1.0 小米/美图
bigEyes 大眼 0 ~ 100 0 0=关闭,100=最大放大 bigEyes / 1000.0 ~ 1.0 小米/美图
lipColor 唇色 0 ~ 100 0 0=关闭,100=最强唇色 lipColor / 1000.0 ~ 1.0 小米/美图
blush 腮红 0 ~ 100 0 0=关闭,100=最强腮红 blush / 1000.0 ~ 1.0 小米/美图
eyebrow 眉毛 0 ~ 100 0 0=关闭,100=最深 eyebrow / 1000.0 ~ 1.0 小米/美图
bodyEnhancement 美体 -30 ~ +30 0 负值=压缩,正值=拉伸上半身 strength / 30 * 0.15 → 拉伸系数 国产美体
legExtension 长腿 0 ~ 50 0 0=关闭,50=最大拉伸 strength / 50 * 0.15 → 拉伸系数 国产美体

调色(Adjustment)

参数 UI 范围 默认值 语义 引擎归一化 参考来源
brightness 亮度 -100 ~ +100 0 整体明暗偏移 / 100-1.0 ~ +1.0 Apple Photos
exposure 曝光 -100 ~ +100 0 模拟曝光补偿 coerceIn(-10, +10) → Shader 曝光 Apple Photos
contrast 对比度 0 ~ 200 50 50=原图,0=最低,200=最高 / 500.0 ~ 4.0 等价 Apple -100 ~ +100
saturation 饱和度 0 ~ 200 100 100=原图,0=灰度,200=最高 / 1000.0 ~ 2.0 等价 Apple -100 ~ +100
temperature 色温 2000K ~ 8000K 5000K 低=冷(蓝),高=暖(黄) (T-5000)/3000-1.0 ~ +1.0 Apple Warmth + Kelvin
tint 色调 -100 ~ +100 0 绿↔︎品红偏移 / 100-1.0 ~ +1.0 Apple Photos
vignette 暗角 0 ~ 100 0 0=关闭,100=最强 待 Phase 2 实现 Apple Photos

滤镜(Filter)

滤镜 类型 推荐场景 说明
NONE 通用 直通
LEICA_CLASSIC 色调矩阵 人像、街拍 降低蓝绿通道,模拟德味
LEICA_VIBRANT 饱和度 风景、美食 饱和度 +30%
LEICA_BW 饱和度=0 人文、建筑 黑白
FILM_GOLD 色调矩阵 人像、日落 暖黄胶片感
FILM_FUJI 色调矩阵 风景、绿植 偏青绿胶片感
VINTAGE 色调矩阵 复古主题 褪色、暖调
COOL 色调矩阵 雪景、夜景 增强蓝色
WARM 色调矩阵 美食、日落 增强红黄

4.3 推荐预设值(MVP)

所有预设以「自然、克制、可二次微调」为原则,避免一键后过曝、过磨、过饱和。

自拍(SELFIE)

{
  "beauty": { "smoothing": 35, "whitening": 25, "slimFace": 10, "bigEyes": 15, "lipColor": 25, "blush": 10, "eyebrow": 10 },
  "filter": { "colorFilter": "NONE", "styleFilter": "NONE" },
  "adjustment": { "brightness": 5, "exposure": 0, "contrast": 52, "saturation": 102, "temperature": 5200, "tint": 2 }
}

人像(PORTRAIT)

{
  "beauty": { "smoothing": 25, "whitening": 20, "slimFace": 5, "bigEyes": 10, "lipColor": 20, "blush": 8, "eyebrow": 8 },
  "filter": { "colorFilter": "FILM_GOLD", "styleFilter": "NONE" },
  "adjustment": { "brightness": 3, "exposure": 0, "contrast": 53, "saturation": 103, "temperature": 5300, "tint": 2 }
}

合影(GROUP)

{
  "beauty": { "smoothing": 20, "whitening": 15, "slimFace": 0, "bigEyes": 0, "lipColor": 10, "blush": 5, "eyebrow": 5 },
  "filter": { "colorFilter": "NONE", "styleFilter": "NONE" },
  "adjustment": { "brightness": 3, "exposure": 0, "contrast": 52, "saturation": 102, "temperature": 5200, "tint": 1 }
}

美食(FOOD)

{
  "beauty": { "enabled": false },
  "filter": { "colorFilter": "LEICA_VIBRANT", "styleFilter": "NONE" },
  "adjustment": { "brightness": 2, "exposure": 0, "contrast": 55, "saturation": 110, "temperature": 5400, "tint": 3 }
}

风景(LANDSCAPE)

{
  "beauty": { "enabled": false },
  "filter": { "colorFilter": "LEICA_VIBRANT", "styleFilter": "NONE" },
  "adjustment": { "brightness": 0, "exposure": 0, "contrast": 58, "saturation": 110, "temperature": 5000, "tint": 0 }
}

夜景/暗光(LOW_LIGHT)

{
  "beauty": { "smoothing": 15, "whitening": 10 },
  "filter": { "colorFilter": "WARM", "styleFilter": "NONE" },
  "adjustment": { "brightness": 12, "exposure": 5, "contrast": 55, "saturation": 100, "temperature": 5600, "tint": 3 }
}

文档(DOCUMENT)

{
  "beauty": { "enabled": false },
  "filter": { "colorFilter": "NONE", "styleFilter": "NONE" },
  "adjustment": { "brightness": 8, "exposure": 0, "contrast": 60, "saturation": 95, "temperature": 5000, "tint": 0 }
}

通用(GENERAL)

{
  "beauty": { "smoothing": 15, "whitening": 10 },
  "filter": { "colorFilter": "NONE", "styleFilter": "NONE" },
  "adjustment": { "brightness": 2, "exposure": 0, "contrast": 52, "saturation": 100, "temperature": 5000, "tint": 0 }
}

5. 数据模型与 Capability 接口

5.1 Capability 注册

Capability(
    name = "ai_optimize",
    description = "分析照片场景并自动推荐美颜/滤镜/调节参数,支持一键优化",
    schema = AiOptimizeCapabilitySchema
)

5.2 输入模型

data class AiOptimizeRequest(
    val imageUri: String,
    val mode: OptimizeMode = OptimizeMode.FAST,
    val source: OptimizeSource = OptimizeSource.GALLERY_VIEWER,
    val allowCloud: Boolean = false
)

enum class OptimizeMode { FAST, SMART }
enum class OptimizeSource { GALLERY_VIEWER, EDITOR, CHAT, BATCH, IM_REMOTE }

5.3 输出模型

data class AiOptimizeResult(
    val scene: Scene,
    val confidence: Float,
    val preset: OptimizePreset,
    val explanation: String,
    val usedCloud: Boolean,
    val processingTimeMs: Long
)

5.4 核心类设计

class AiOptimizeCapability(
    private val sceneAnalyzer: SceneAnalyzer,
    private val presetRepository: PresetRepository,
    private val smartEngine: SmartOptimizeEngine? = null,
    private val consentManager: CloudOptimizeConsentManager
) : Capability {

    override val name: String = "ai_optimize"
    override val description: String = "分析照片场景并自动推荐美颜/滤镜/调节参数"

    override suspend fun execute(request: CapabilityRequest): CapabilityResponse {
        val optimizeRequest = request.parseAs<AiOptimizeRequest>()

        return try {
            when (optimizeRequest.mode) {
                OptimizeMode.FAST -> fastOptimize(optimizeRequest)
                OptimizeMode.SMART -> smartOptimize(optimizeRequest)
            }
        } catch (e: Exception) {
            Logger.e("AiOptimize", "Optimization failed", e)
            fallbackFastOptimize(optimizeRequest)
        }
    }

    private suspend fun fastOptimize(request: AiOptimizeRequest): CapabilityResponse {
        val startTime = SystemClock.elapsedRealtime()
        val analysis = sceneAnalyzer.analyze(request.imageUri)
        val preset = presetRepository.getPreset(analysis.scene)
        val elapsed = SystemClock.elapsedRealtime() - startTime

        val result = AiOptimizeResult(
            scene = analysis.scene,
            confidence = analysis.confidence,
            preset = preset,
            explanation = buildExplanation(analysis.scene),
            usedCloud = false,
            processingTimeMs = elapsed
        )

        return CapabilityResponse.Success(result)
    }

    private suspend fun smartOptimize(request: AiOptimizeRequest): CapabilityResponse {
        if (!consentManager.isCloudOptimizeAllowed()) {
            return CapabilityResponse.NeedConsent("cloud_optimize")
        }
        if (smartEngine == null) {
            return fastOptimize(request)
        }
        return smartEngine.optimize(request)
    }

    private fun fallbackFastOptimize(request: AiOptimizeRequest): CapabilityResponse {
        val preset = presetRepository.getPreset(Scene.GENERAL)
        return CapabilityResponse.Success(
            AiOptimizeResult(
                scene = Scene.GENERAL,
                confidence = 0.5f,
                preset = preset,
                explanation = context.getString(R.string.ai_optimize_fallback_explanation),
                usedCloud = false,
                processingTimeMs = 0
            )
        )
    }
}

5.5 与编辑器集成

class PhotoEditorViewModel(
    private val aiOptimizeCapability: AiOptimizeCapability,
    private val recipeApplier: RecipeApplier,
    private val history: EditHistory
) : ViewModel() {

    fun onAiOptimizeClick() {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isAiOptimizing = true)

            val request = AiOptimizeRequest(
                imageUri = currentImageUri,
                mode = OptimizeMode.FAST,
                source = OptimizeSource.EDITOR
            )

            when (val response = aiOptimizeCapability.execute(CapabilityRequest(request))) {
                is CapabilityResponse.Success -> {
                    val result = response.data as AiOptimizeResult
                    val newRecipe = OptimizeRecipeMapper.toEditRecipe(
                        preset = result.preset,
                        baseRecipe = history.current
                    )
                    history.push(newRecipe)
                    renderPreview()
                }
                is CapabilityResponse.NeedConsent -> {
                    _events.emit(EditorEvent.ShowCloudConsentDialog)
                }
                is CapabilityResponse.Error -> {
                    _events.emit(EditorEvent.ShowError(response.message))
                }
            }

            _uiState.value = _uiState.value.copy(isAiOptimizing = false)
        }
    }
}

5.6 Agent Tool Spec

{
  "type": "function",
  "function": {
    "name": "ai_optimize",
    "description": "分析照片场景并自动推荐美颜、滤镜、调节参数,一键优化图片。",
    "parameters": {
      "type": "object",
      "properties": {
        "image_uri": {
          "type": "string",
          "description": "待优化图片的本地文件 URI"
        },
        "mode": {
          "type": "string",
          "enum": ["fast", "smart"],
          "description": "优化模式:fast 为本地快速优化(默认),smart 为云端智能推荐"
        }
      },
      "required": ["image_uri"],
      "additionalProperties": false
    }
  }
}

6. 错误处理与降级策略

错误场景 处理策略 用户反馈
本地分析超时 使用 GENERAL preset “已应用通用优化”
ML Kit 不可用 使用 GENERAL preset “已应用通用优化”
远程模型超时 fallback 到 FAST 路径 “网络较慢,已使用本地优化”
远程模型返回非法 JSON fallback 到 FAST 路径 “智能推荐失败,已使用本地优化”
用户未授权云端 返回 NeedConsent 显示授权弹窗
图片加载失败 返回 Error “无法加载图片,请重试”
GPU 处理失败 返回 Error “处理失败,请手动编辑”

7. 性能要求

路径 P50 P95 测量点
Fast 场景分析 < 200ms < 400ms 从点击到返回 SceneAnalysis
Fast 端到端 < 1s < 1.5s 从点击到显示推荐卡片
媒体查看器应用保存 < 2s < 3s 从点击「应用」到进入对比模式
Smart 端到端 < 2s < 4s 从点击「换一换」到返回新推荐
批量处理单张 < 1.5s < 2.5s 多选批量模式下单张平均

8. 隐私与安全


9. 验收指标

指标 MVP 目标 测量方式
AI 优化按钮点击率 > 30%(进入查看器/编辑器的用户) 埋点
应用率(点击后保存) > 60% 埋点
微调率(点击后进入编辑器调整) < 40% 埋点
本地路径处理时间 < 1s(P50) 日志
场景识别准确率 > 80%(5 个核心场景) 人工标注样本
崩溃率 0 Crashlytics

9.1 代码侧改动清单

9.2 验收标准


10. Agent Task 拆解

Task ID 名称 Assignee Priority 依赖
aio-001 场景分析器 SceneAnalyzer RD P0 -
aio-002 本地预设库 PresetRepository RD P0 -
aio-003 AI 优化 Capability RD P0 aio-001, aio-002
aio-004 媒体查看器 AI 优化入口 RD P0 aio-003
aio-005 编辑器 AI 一键优化入口 RD P0 aio-003
aio-006 优化结果保存与对比模式 RD P0 aio-004, aio-005
aio-007 隐私授权与设置开关 RD P1 aio-003
aio-008 远程 Smart 优化引擎 RD P1 aio-007
aio-009 AI 对话命令集成 RD P1 aio-003
aio-010 批量 AI 优化 RD P1 aio-003, aio-006
aio-011 验收测试与性能基准 QA P0 aio-004, aio-005, aio-006
aio-012 架构合规审查 CR P0 aio-003 完成后

10.1 [agent-task:aio-001] 场景分析器 SceneAnalyzer

10.2 [agent-task:aio-002] 本地预设库 PresetRepository

10.3 [agent-task:aio-003] AI 优化 Capability


11. 相关文档索引

文档 说明
docs/01-PRODUCT/FEATURES.md#141-ai-一键优化 交互 PRD
docs/03-TECHNICAL-SPECS/BEAUTY_ENGINE_TECH_SPEC.md 大美丽美颜引擎
docs/02-ARCHITECTURE/AGENT_ARCHITECTURE.md Agent 架构
app/src/main/java/com/mamba/picme/features/editor/AGENTS.md 编辑器模块规范
app/src/main/java/com/mamba/picme/features/gallery/AGENTS.md 相册模块规范