优化图片创作
This commit is contained in:
@@ -64,6 +64,9 @@ IMAGE_PRESETS: dict[str, str] = {
|
||||
"黑金高级": "黑金奢华商业摄影,深黑背景,金色高光,低调曝光,高对比度,强烈明暗塑形,精准轮廓光,金属反射质感,高级镜面反射,深邃黑位,暖金色点缀,低饱和、精致、克制、奢华,高端广告摄影质感。",
|
||||
"冷峻科技": "现代科技商业摄影,冷灰蓝色调,低饱和,高级冷色温,干净硬朗的光线,精准边缘光,金属与玻璃质感清晰,适度高对比,深灰阴影,简洁现代,锐利清晰但不过度数字化,真实产品摄影质感,理性、专业、克制,避免科幻全息、机器人和过度AI视觉元素。",
|
||||
"赛博朋克": "赛博朋克摄影风格,蓝紫与洋红霓虹色调,高饱和霓虹光,强烈冷暖色彩碰撞,高对比,深黑阴影,彩色轮廓光,霓虹反射,局部RGB光效,未来都市视觉语言,强烈视觉冲击,暗部层次丰富,真实摄影质感,科技感与潮流感结合,避免雨天效果。",
|
||||
"日系手绘动画": "经典日系手绘动画电影质感,柔和自然配色,清新青绿与天空蓝色调,温暖阳光,细腻手绘线条,水彩与赛璐璐结合质感,柔和阴影,自然光影,丰富植物细节,轻微纸张与颜料肌理,童话般自然环境,宁静治愈,清新、温暖、诗意、生活感,具有传统二维动画电影质感,避免3D塑料感、过度数字化和强烈锐化。",
|
||||
"国风水墨": "中国传统水墨画风格,黑白灰墨色体系,淡青与赭石少量点染,水墨晕染,浓淡干湿变化,焦墨、淡墨与泼墨结合,宣纸自然肌理,山水皴法,虚实相生,大面积留白,云雾朦胧,柔和层次,写意而不过度抽象,空灵、含蓄、诗意、东方禅意,强调墨韵与意境,避免高饱和、现代摄影感和西式油画质感。",
|
||||
"新中式": "现代新中式东方美学,传统中国元素与现代极简设计融合,黑白灰、原木色、墨绿与低饱和暖色体系,大面积留白,克制高级配色,简洁几何构图,中式格栅、山石、竹、松、水景等东方元素适度点缀,柔和自然光,细腻材质,现代空间感与传统意境结合,宋式审美,安静、雅致、克制、高级,商业视觉质感,避免大红大金、复杂雕花和俗艳传统元素。",
|
||||
}
|
||||
|
||||
# 来源于「图片创作预设.docx」的统一生成收束。用户界面只展示预设标题;
|
||||
|
||||
@@ -1310,12 +1310,20 @@ class PresetGuidanceTests(CreationAgentBaseTests):
|
||||
self.assertIn("避免过度HDR", prompt)
|
||||
self.assertEqual(apply_image_preset_prompt("电影感", prompt), prompt)
|
||||
|
||||
def test_new_image_preset_style_is_added_to_the_actual_image_prompt(self):
|
||||
from .creation_presets import apply_image_preset_prompt
|
||||
|
||||
prompt = apply_image_preset_prompt("国风水墨", "画一只白瓷茶杯")
|
||||
self.assertIn("【图片风格预设】国风水墨", prompt)
|
||||
self.assertIn("中国传统水墨画风格", prompt)
|
||||
self.assertIn("避免高饱和、现代摄影感", prompt)
|
||||
|
||||
def test_every_frontend_preset_has_guidance(self):
|
||||
"""前端 9 个视频 + 9 个图片预设都要有拍法,漏一个就等于那张卡是摆设。"""
|
||||
"""前端 9 个视频 + 12 个图片预设都要有拍法,漏一个就等于那张卡是摆设。"""
|
||||
from .creation_presets import IMAGE_PRESETS, VIDEO_PRESETS
|
||||
|
||||
self.assertEqual(len(VIDEO_PRESETS), 9)
|
||||
self.assertEqual(len(IMAGE_PRESETS), 9)
|
||||
self.assertEqual(len(IMAGE_PRESETS), 12)
|
||||
self.assertTrue(all(text.strip() for text in {**VIDEO_PRESETS, **IMAGE_PRESETS}.values()))
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 535 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
@@ -156,9 +156,11 @@
|
||||
.login-page .login-form-panel {
|
||||
position: relative;
|
||||
z-index: auto;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
align-content: safe center;
|
||||
justify-items: center;
|
||||
gap: 16px;
|
||||
padding: clamp(48px, 6vw, 106px);
|
||||
background: transparent;
|
||||
}
|
||||
@@ -203,7 +205,8 @@
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: min(100%, 520px);
|
||||
height: 548px;
|
||||
height: auto;
|
||||
min-height: 0;
|
||||
padding: 44px 46px 38px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.28);
|
||||
@@ -452,11 +455,12 @@
|
||||
|
||||
.login-page .login-submit {
|
||||
height: 54px;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
margin-top: 2px;
|
||||
border: 0;
|
||||
border-radius: 11px;
|
||||
color: #fff;
|
||||
@@ -478,51 +482,130 @@
|
||||
filter: saturate(0.85);
|
||||
}
|
||||
.login-page .login-submit:disabled svg { animation: login-spin 800ms linear infinite; }
|
||||
.login-page .login-submit svg { width: 17px; height: 17px; }
|
||||
.login-page .login-submit svg { width: 17px; height: 17px; flex: 0 0 auto; }
|
||||
|
||||
.login-page .login-extras {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
left: 50%;
|
||||
bottom: 28px;
|
||||
width: min(calc(100% - 48px), 520px);
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
color: rgba(255, 255, 255, 0.48);
|
||||
font-size: 12px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.login-page .login-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
color: rgba(255, 255, 255, 0.48);
|
||||
font-size: 12px;
|
||||
}
|
||||
.login-page .login-row label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.login-page .login-row input[type="checkbox"] {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
flex: 0 0 auto;
|
||||
accent-color: #7da1ff;
|
||||
}
|
||||
.login-page .login-row a,
|
||||
.login-page .login-switch a {
|
||||
color: rgba(183, 204, 255, 0.88);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.login-page .login-row a:hover,
|
||||
.login-page .login-switch a:hover { text-decoration: underline; }
|
||||
|
||||
/* 三入口操作条:同宽收进卡片,小屏改纵向避免撑破 */
|
||||
.login-page .login-actions {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr);
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 11px;
|
||||
background: linear-gradient(135deg, #002d9f, #001d70 76%);
|
||||
box-shadow: 0 14px 30px rgba(0, 25, 102, 0.32);
|
||||
}
|
||||
.login-page .login-actions .login-submit {
|
||||
margin-top: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.login-page .login-actions .login-submit:hover:not(:disabled) {
|
||||
transform: none;
|
||||
filter: brightness(1.08);
|
||||
box-shadow: none;
|
||||
}
|
||||
.login-page .login-action-alt {
|
||||
min-width: 0;
|
||||
height: 54px;
|
||||
padding: 0 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
color: rgba(255, 255, 255, 0.88);
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
cursor: pointer;
|
||||
}
|
||||
.login-page .login-action-alt + .login-submit,
|
||||
.login-page .login-submit + .login-action-alt {
|
||||
box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
.login-page .login-action-alt span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.login-page .login-action-alt:hover { background: rgba(255, 255, 255, 0.08); }
|
||||
.login-page .login-action-alt svg { width: 14px; height: 14px; flex: 0 0 auto; }
|
||||
|
||||
.login-page .login-switch {
|
||||
margin: 18px 0 0;
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.48);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.login-page .login-card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 7px;
|
||||
margin-top: 14px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
font-size: 10px;
|
||||
}
|
||||
.login-page .login-card-footer svg { width: 13px; height: 13px; }
|
||||
|
||||
/* 注册页仍可能引用旧 extras 容器,保留文档流兜底 */
|
||||
.login-page .login-extras {
|
||||
position: static;
|
||||
z-index: 2;
|
||||
width: min(100%, 520px);
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
color: rgba(255, 255, 255, 0.48);
|
||||
font-size: 12px;
|
||||
transform: none;
|
||||
}
|
||||
.login-page .login-sso {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
.login-page .login-sso button {
|
||||
min-width: 0;
|
||||
height: 36px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -537,24 +620,7 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
.login-page .login-sso button:hover { background: rgba(255, 255, 255, 0.08); }
|
||||
.login-page .login-sso svg { width: 14px; height: 14px; }
|
||||
|
||||
.login-page .login-switch {
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.48);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.login-page .login-card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 7px;
|
||||
margin-top: 26px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
font-size: 10px;
|
||||
}
|
||||
.login-page .login-card-footer svg { width: 13px; height: 13px; }
|
||||
.login-page .login-sso svg { width: 14px; height: 14px; flex: 0 0 auto; }
|
||||
|
||||
.login-page .login-note {
|
||||
margin: 0;
|
||||
@@ -649,6 +715,9 @@
|
||||
}
|
||||
.login-page .login-visual { display: none; }
|
||||
.login-page .login-form-panel {
|
||||
align-content: start;
|
||||
justify-items: center;
|
||||
gap: 16px;
|
||||
overflow: auto;
|
||||
padding: 32px 20px 28px;
|
||||
}
|
||||
@@ -674,6 +743,70 @@
|
||||
position: static;
|
||||
width: min(100%, 480px);
|
||||
transform: none;
|
||||
margin-top: 16px;
|
||||
margin-top: 0;
|
||||
}
|
||||
.login-page .login-card-heading { margin-bottom: 28px; }
|
||||
.login-page .login-form { gap: 14px; }
|
||||
}
|
||||
|
||||
/* 窄屏:主登录在上,两侧入口两列在下 */
|
||||
@media (max-width: 560px) {
|
||||
.login-page .login-form-panel {
|
||||
padding: 24px 14px 20px;
|
||||
}
|
||||
.login-page .login-card {
|
||||
width: min(100%, 480px);
|
||||
padding: 28px 16px 22px;
|
||||
}
|
||||
.login-page .login-actions {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
overflow: visible;
|
||||
}
|
||||
.login-page .login-actions .login-submit {
|
||||
grid-column: 1 / -1;
|
||||
order: -1;
|
||||
border-radius: 11px;
|
||||
background: linear-gradient(135deg, #002d9f, #001d70 76%);
|
||||
box-shadow: 0 14px 30px rgba(0, 25, 102, 0.32);
|
||||
}
|
||||
.login-page .login-actions .login-submit:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 18px 36px rgba(0, 23, 94, 0.4);
|
||||
filter: brightness(1.06);
|
||||
}
|
||||
.login-page .login-action-alt,
|
||||
.login-page .login-action-alt + .login-submit,
|
||||
.login-page .login-submit + .login-action-alt {
|
||||
box-shadow: none;
|
||||
}
|
||||
.login-page .login-action-alt {
|
||||
height: 44px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.045);
|
||||
}
|
||||
.login-page .login-row {
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 矮屏:顶部对齐可滚动,避免辅助入口与主按钮重叠 */
|
||||
@media (max-height: 800px) {
|
||||
.login-page .login-form-panel {
|
||||
align-content: start;
|
||||
gap: 16px;
|
||||
overflow-y: auto;
|
||||
padding-top: 28px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
.login-page .login-card {
|
||||
height: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
.login-page .login-card-heading { margin-bottom: 24px; }
|
||||
.login-page .login-form { gap: 14px; }
|
||||
}
|
||||
|
||||
@@ -552,14 +552,6 @@ export function AuthScreen({
|
||||
<p className={`login-error${error ? " show" : ""}`} role="alert">
|
||||
{error || "账号或密码不正确,请重新输入。"}
|
||||
</p>
|
||||
<button className="login-submit" type="submit" disabled={busy}>
|
||||
{busy ? (LOGIN_PROGRESS_COPY[loginProgress || "checking"] || "正在进入工作台") : "确认登录"}
|
||||
{busy ? <LoaderCircle /> : <ArrowRight />}
|
||||
</button>
|
||||
</form>
|
||||
<p className="login-card-footer"><Lock />登录信息仅用于当前演示会话</p>
|
||||
</div>
|
||||
<div className="login-extras">
|
||||
<div className="login-row">
|
||||
<label>
|
||||
<input type="checkbox" checked={remember} onChange={(event) => setRemember(event.target.checked)} />
|
||||
@@ -567,17 +559,23 @@ export function AuthScreen({
|
||||
</label>
|
||||
<a href="#" onClick={(event) => { event.preventDefault(); showToast("重置密码", "请联系团队超管重置你的登录密码"); }}>忘记密码?</a>
|
||||
</div>
|
||||
<div className="login-sso">
|
||||
<button type="button" onClick={() => showToast("微信扫码", "对接中 · 当前请用账号 + 密码登录")}>
|
||||
<ScanLine /> 微信扫码
|
||||
<div className="login-actions">
|
||||
<button type="button" className="login-action-alt" onClick={() => showToast("微信扫码", "对接中 · 当前请用账号 + 密码登录")}>
|
||||
<ScanLine /> <span>微信扫码</span>
|
||||
</button>
|
||||
<button type="button" onClick={() => showToast("飞书 SSO", "对接中 · 当前请用账号 + 密码登录")}>
|
||||
<ShieldCheck /> 飞书 SSO
|
||||
<button className="login-submit" type="submit" disabled={busy}>
|
||||
{busy ? (LOGIN_PROGRESS_COPY[loginProgress || "checking"] || "正在进入工作台") : "确认登录"}
|
||||
{busy ? <LoaderCircle /> : <ArrowRight />}
|
||||
</button>
|
||||
<button type="button" className="login-action-alt" onClick={() => showToast("飞书 SSO", "对接中 · 当前请用账号 + 密码登录")}>
|
||||
<ShieldCheck /> <span>飞书 SSO</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<p className="login-switch">
|
||||
还没账号? <a href="/register" onClick={(event) => { event.preventDefault(); switchMode("register"); }}>注册团队 →</a>
|
||||
</p>
|
||||
<p className="login-card-footer"><Lock />登录信息仅用于当前演示会话</p>
|
||||
</div>
|
||||
</main>
|
||||
{toastNode}
|
||||
|
||||
@@ -59,6 +59,9 @@ const IMAGE_PRESETS: PresetItem[] = [
|
||||
{ name: "黑金高级", category: "style", mode: "image", title: "黑金高级", cover: "/assets/image-presets/black-gold.png" },
|
||||
{ name: "冷峻科技", category: "style", mode: "image", title: "冷峻科技", cover: "/assets/image-presets/tech-cool.png" },
|
||||
{ name: "赛博朋克", category: "style", mode: "image", title: "赛博朋克", cover: "/assets/image-presets/cyberpunk.png" },
|
||||
{ name: "日系手绘动画", category: "style", mode: "image", title: "日系手绘动画", cover: "/assets/image-presets/japanese-hand-drawn-anime.png" },
|
||||
{ name: "国风水墨", category: "style", mode: "image", title: "国风水墨", cover: "/assets/image-presets/chinese-ink-wash.png" },
|
||||
{ name: "新中式", category: "style", mode: "image", title: "新中式", cover: "/assets/image-presets/neo-chinese.png" },
|
||||
];
|
||||
|
||||
const VIDEO_FILTERS = [
|
||||
|
||||
Reference in New Issue
Block a user