"use client"; import { ArrowDown, ArrowUp, Check, Layers, Loader2, Menu, Move3D, Plus, RefreshCw, Save, Sparkles, Trash2, Upload, } from "lucide-react"; import { CanvasToolbarIcon } from "@/components/canvas/CanvasToolbarIcon"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Separator } from "@/components/ui/separator"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; import { AI_WASH_CONTROL_ORDER, type AiWashControlId, } from "@/lib/ai-wash/config"; import { ENHANCE_PRO_KREA_DEFAULT_BASE_URL, ENHANCE_PRO_KREA_DEFAULT_MODEL, ENHANCE_PRO_KREA_MODELS, type EnhanceProKreaModel, type EnhanceProPreset, } from "@/lib/enhance-pro/config"; import { cn } from "@/lib/utils"; import type { EnhanceProKeyRow, LocalAiImagePipelineSectionsProps, } from "../../_lib/types"; import { LocalAiGroupHeading, LocalAiSectionShell, LocalAiSectionSummary, } from "../local-ai-section-shell"; export function LocalAiImagePipelineSections({ modelsData, rmbgConfig, setRmbgConfig, enhanceConfig, setEnhanceConfig, enhanceProConfig, setEnhanceProConfig, enhanceProApiKeysDraft, setEnhanceProApiKeysDraft, enhanceProApiKeysDraftCount, draftEnhanceProKeyRows, savedEnhanceProKeyRows, enhanceProPresetEditorMode, setEnhanceProPresetEditorMode, selectedEnhanceProPresetId, setSelectedEnhanceProPresetId, selectedEnhanceProPreset, selectedEnhanceProPresetIndex, draggingEnhanceProPresetId, aiWashConfig, setAiWashConfig, aiWashModeIconUploading, extendConfig, setExtendConfig, watermarkRemoveConfig, setWatermarkRemoveConfig, angleEditConfig, setAngleEditConfig, pointsSystemConfig, updatePointsCostField, layerSplitConfig, setLayerSplitConfig, isLocalAiSectionExpanded, toggleLocalAiSection, renderEnhanceProPresetEditor, getEnhanceProPresetSummary, handleSaveRmbgConfig, handleSaveEnhanceConfig, handleSaveEnhanceProConfig, handleAddEnhanceProPoolKey, handleDeleteEnhanceProPoolKey, handleToggleEnhanceProModelVisible, handleAddEnhanceProPreset, handleResetEnhanceProPresets, handleEnhanceProPresetDragStart, handleEnhanceProPresetDragEnd, handleEnhanceProPresetDrop, handleMoveEnhanceProPreset, handleAiWashModeIconUpload, handleSaveAiWashConfig, handleSaveExtendConfig, handleSaveWatermarkRemoveConfig, handleSaveAngleEditConfig, handleSaveLayerSplitConfig, }: LocalAiImagePipelineSectionsProps) { const availableImageModels = (modelsData?.models || []).filter( (model) => model.supportsImageGen && model.isEnabled ); const formatAiWashModelOptionLabel = (model: (typeof availableImageModels)[number]) => `${model.displayName || model.modelId}${model.isHidden ? " · 前台隐藏" : ""}`; const getAiWashControlToneCopy = (controlId: AiWashControlId) => { if (controlId === "creativity") { return "每档可以单独指定模型;如果留空,前台才会开放模型下拉选择。"; } if (controlId === "detail") { return "每档可以补充默认提示词,决定细节精修的强弱。"; } return "每档可以补充默认提示词,决定光影、氛围与空间塑造。"; }; return ( <> {/* 抠图API配置 */} 配置背景移除API,用于画图标注功能中的抠图处理。支持自部署RMBG、PhotoRoom和AOS云服务。 } expanded={isLocalAiSectionExpanded("rmbg")} id="local-ai-section-rmbg" onToggle={() => toggleLocalAiSection("rmbg")} summary={ } title="抠图API配置" > {/* 服务提供商选择 */}
setRmbgConfig({ ...rmbgConfig, provider: "vip98k" })} >
{rmbgConfig.provider === "vip98k" && }

VIP98K 统一服务

setRmbgConfig({ ...rmbgConfig, provider: "rmbg" })} >
{rmbgConfig.provider === "rmbg" && ( )}

RMBG-2.0 (自部署)

setRmbgConfig({ ...rmbgConfig, provider: "photoroom" }) } >
{rmbgConfig.provider === "photoroom" && ( )}

PhotoRoom (云服务)

setRmbgConfig({ ...rmbgConfig, provider: "aoscdn" }) } >
{rmbgConfig.provider === "aoscdn" && ( )}

AOS Segmentation

{rmbgConfig.provider === "vip98k" && (
使用 VIP98K 的 remove-background 模型。API Key 从“AI 模型设置”中的 VIP98K 服务商读取,不会在此重复保存。
)} {/* RMBG 配置 */} {rmbgConfig.provider === "rmbg" && ( <>
RMBG-2.0 配置
setRmbgConfig({ ...rmbgConfig, apiUrl: e.target.value }) } placeholder="http://156.225.27.52:8000" value={rmbgConfig.apiUrl} />
请输入完整的API地址,例如: http://156.225.27.52:8000
setRmbgConfig({ ...rmbgConfig, apiKey: e.target.value }) } placeholder="如果API需要密钥,请在此输入" type="password" value={rmbgConfig.apiKey} />
RMBG-2.0 说明

• 需要自行部署RMBG-2.0服务

• 系统会自动调用 /rmbg/base64 接口进行抠图处理

• 支持的图片格式:JPG, PNG, JPEG等常见格式

)} {/* PhotoRoom 配置 */} {rmbgConfig.provider === "photoroom" && ( <>
PhotoRoom 配置
setRmbgConfig({ ...rmbgConfig, photoroomApiKey: e.target.value, }) } placeholder="输入PhotoRoom API密钥" type="password" value={rmbgConfig.photoroomApiKey} />
在 PhotoRoom 开发者平台获取API密钥
PhotoRoom 说明

• 使用 PhotoRoom 云服务进行高清抠图

• 支持 HD 高清背景移除,效果更好

• API文档:https://www.photoroom.com/api

• 按调用次数计费,请注意用量

)} {/* AOS 配置 */} {rmbgConfig.provider === "aoscdn" && ( <>
AOS Segmentation 配置
setRmbgConfig({ ...rmbgConfig, aosApiKey: e.target.value, }) } placeholder="输入 AOS X-API-KEY" type="password" value={rmbgConfig.aosApiKey} />
setRmbgConfig({ ...rmbgConfig, aosApiBaseUrl: e.target.value, }) } placeholder="https://techsz.aoscdn.com" value={rmbgConfig.aosApiBaseUrl} />
默认使用官方地址,可按需替换。
关闭时保持原图尺寸,开启时按主体区域裁剪。
setRmbgConfig({ ...rmbgConfig, aosCrop: checked }) } /> {rmbgConfig.aosCrop ? "已开启" : "已关闭"}
AOS 说明

• 使用异步任务模式(1秒轮询,最多30秒)

• 接口返回链接有效期1小时,系统会自动转存到你的存储桶

• 官方限制:图片最大20MB,分辨率最大4096x4096

)}
{/* 变清晰API配置 */} 配置图片变清晰服务,用于画图标注功能中的图片增强处理。 } expanded={isLocalAiSectionExpanded("enhance")} id="local-ai-section-enhance" onToggle={() => toggleLocalAiSection("enhance")} summary={ } title="变清晰API配置" > {enhanceConfig.provider === "vip98k" ? (
使用 VIP98K 的 enhance 模型,默认 4 倍增强。API Key 从“AI 模型设置”中的 VIP98K 服务商读取。
) : ( <> {/* API切换开关 */}
启用后将使用Real-ESRGAN本地模型进行图片增强,效果更好
setEnhanceConfig({ ...enhanceConfig, useBackupApi: checked, }) } /> {enhanceConfig.useBackupApi ? "已开启" : "已关闭"}
{/* 主API配置 */} {!enhanceConfig.useBackupApi && ( <>
主API配置 (第三方云服务)
setEnhanceConfig({ ...enhanceConfig, apiUrl: e.target.value, }) } placeholder="https://techsz.aoscdn.com" value={enhanceConfig.apiUrl} />
请输入完整的API地址,例如: https://techsz.aoscdn.com
setEnhanceConfig({ ...enhanceConfig, apiKey: e.target.value, }) } placeholder="请输入API密钥" type="password" value={enhanceConfig.apiKey} />
API密钥是必需的,请从服务提供商获取
选择图片类型:通用或人像(人像模式最多同时处理10个人)
选择放大倍数:自动(根据图片尺寸智能选择)、不放大、2倍或4倍
主API文档说明

• API地址应指向服务根地址,例如: https://techsz.aoscdn.com

• 系统会自动调用 /api/tasks/visual/scale 接口进行变清晰处理

• 支持的图片格式:JPG, JPEG, PNG, BMP, WEBP, TIFF等

• 图片大小:不超过50MB,不限制分辨率(建议按业务需求控制尺寸)

• 返回的链接有效期为1小时,系统会自动下载并存储到S3

)} {/* 备用API配置 (Real-ESRGAN) */} {enhanceConfig.useBackupApi && ( <>
备用API配置 (Real-ESRGAN 本地模型)
setEnhanceConfig({ ...enhanceConfig, backupApiUrl: e.target.value, }) } placeholder="http://156.225.27.52:5233" value={enhanceConfig.backupApiUrl} />
Real-ESRGAN API服务地址,默认: http://156.225.27.52:5233
setEnhanceConfig({ ...enhanceConfig, backupApiKey: e.target.value, }) } placeholder="请输入Real-ESRGAN API密钥" type="password" value={enhanceConfig.backupApiKey} />
API密钥用于认证,请从管理员处获取
推荐使用4倍放大,效果最佳
不同模型适用于不同场景
Real-ESRGAN API说明

• 基于Real-ESRGAN深度学习模型,图像超分辨率效果更好

• 使用URL方式上传图片,处理后自动保存到S3存储

• 支持2x、4x、8x放大倍数

• 处理时间:通常1-10秒,取决于图片大小

• 支持格式:JPG, PNG, JPEG等常见图片格式

• 文件限制:最大50MB

)} )}
配置 Krea Topaz Generative,用于无限画布中的“图像增强 Pro”能力。 } expanded={isLocalAiSectionExpanded("enhance-pro")} id="local-ai-section-enhance-pro" onToggle={() => toggleLocalAiSection("enhance-pro")} summary={ 0 ? "enabled" : "warning", }, { label: enhanceProConfig.defaultModel || ENHANCE_PRO_KREA_DEFAULT_MODEL, tone: "neutral", }, ]} /> } title="图像增强 Pro 配置" >
关闭后无限画布仍保留普通“高清增强”,但不再开放 Krea Topaz Generative 参数面板。
setEnhanceProConfig((prev) => ({ ...prev, enabled: checked, })) } /> {enhanceProConfig.enabled ? "已开启" : "已关闭"}
setEnhanceProConfig((prev) => ({ ...prev, providerName: e.target.value, })) } placeholder="Krea Topaz Generative" value={enhanceProConfig.providerName} />
setEnhanceProConfig((prev) => ({ ...prev, baseUrl: e.target.value, })) } placeholder={ENHANCE_PRO_KREA_DEFAULT_BASE_URL} value={enhanceProConfig.baseUrl} />
setEnhanceProConfig((prev) => ({ ...prev, apiKey: e.target.value, })) } placeholder="请输入 Krea Bearer Token" type="password" value={enhanceProConfig.apiKey} />
和 Tripo3D 一样,单个 Key 可以直接加入池;批量导入仍支持一次粘贴多行。
Krea Key 池
当前共 {enhanceProConfig.apiKeys.length} 个 Key {enhanceProApiKeysDraft.trim() ? `,本次保存会替换为 ${enhanceProApiKeysDraftCount} 个 Key` : ",留空保存不会覆盖已保存池"} 。增强 Pro 任务会轮询使用可用 Key。