fix(image): 修复图片生成和编辑请求中尺寸参数传递问题
- 添加 resolveRequestSize 函数处理尺寸参数解析逻辑 - 将 pixelSize 变量重命名为 requestSize 以提高代码可读性 - 修复当尺寸为 auto 时不发送 size 参数的功能 - 确保所有非 auto 尺寸值都会正确传递到请求中 - 更新图片生成和编辑函数中的尺寸参数处理逻辑
This commit is contained in:
@@ -2,19 +2,22 @@
|
||||
|
||||
import { BookOpen, CheckSquare, ClipboardPaste, Download, FolderPlus, History, LoaderCircle, Plus, SlidersHorizontal, Sparkles, Trash2, Upload, VideoIcon } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { App, AutoComplete, Button, Checkbox, Drawer, Empty, Input, Modal, Tag, Typography } from "antd";
|
||||
import { App, Button, Checkbox, Drawer, Empty, Input, Modal, Tag, Typography } from "antd";
|
||||
import localforage from "localforage";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
import { AssetPickerModal, type InsertAssetPayload } from "@/app/(user)/canvas/components/asset-picker-modal";
|
||||
import { ModelPicker } from "@/components/model-picker";
|
||||
import { PromptSelectDialog } from "@/components/prompts/prompt-select-dialog";
|
||||
import { VideoSettingsPanel, normalizeVideoResolutionValue, normalizeVideoSizeValue, videoSizeLabel } from "@/components/video-settings-panel";
|
||||
import { canvasThemes } from "@/lib/canvas-theme";
|
||||
import { formatBytes, formatDuration } from "@/lib/image-utils";
|
||||
import { resolveMediaUrl, uploadMediaFile } from "@/services/file-storage";
|
||||
import { uploadImage } from "@/services/image-storage";
|
||||
import { requestVideoGeneration } from "@/services/api/video";
|
||||
import { useAssetStore } from "@/stores/use-asset-store";
|
||||
import { useConfigStore, useEffectiveConfig, type AiConfig } from "@/stores/use-config-store";
|
||||
import { useThemeStore } from "@/stores/use-theme-store";
|
||||
import type { ReferenceImage } from "@/types/image";
|
||||
|
||||
type GeneratedVideo = {
|
||||
@@ -52,9 +55,6 @@ type GenerationLog = {
|
||||
|
||||
type UpdateAiConfig = <K extends keyof AiConfig>(key: K, value: AiConfig[K]) => void;
|
||||
|
||||
const sizeOptions = ["1280x720", "720x1280", "1024x1024", "1792x1024", "1024x1792"].map((value) => ({ label: value, value }));
|
||||
const resolutionOptions = ["720", "480"].map((value) => ({ label: `${value}p`, value }));
|
||||
const secondOptions = ["6", "10", "12", "16", "20"].map((value) => ({ label: `${value}s`, value }));
|
||||
const LOG_STORE_KEY = "infinite-canvas:video_generation_logs";
|
||||
const logStore = localforage.createInstance({ name: "infinite-canvas", storeName: "video_generation_logs" });
|
||||
|
||||
@@ -306,7 +306,7 @@ export default function VideoPage() {
|
||||
|
||||
<div className="flex items-center justify-between rounded-lg border border-stone-200 bg-stone-50 px-3 py-2 text-sm dark:border-stone-800 dark:bg-stone-900 sm:hidden">
|
||||
<span className="truncate text-stone-500 dark:text-stone-400">
|
||||
{model} · {normalizeResolution(effectiveConfig.vquality)}p · {normalizeVideoSize(effectiveConfig.size)} · {normalizeVideoSeconds(effectiveConfig.videoSeconds)}s
|
||||
{model} · {normalizeResolution(effectiveConfig.vquality)}p · {videoSizeLabel(effectiveConfig.size)} · {normalizeVideoSeconds(effectiveConfig.videoSeconds)}s
|
||||
</span>
|
||||
<Button size="small" type="text" icon={<SlidersHorizontal className="size-4" />} onClick={() => setSettingsOpen(true)}>
|
||||
调整
|
||||
@@ -357,8 +357,8 @@ export default function VideoPage() {
|
||||
<Drawer title="生成记录" placement="bottom" size="large" open={logsOpen} onClose={() => setLogsOpen(false)}>
|
||||
<LogPanel logs={logs} selectedLogIds={selectedLogIds} activeLogId={previewLog?.id} onSelectedLogIdsChange={setSelectedLogIds} onCreateSession={createSession} onDeleteSelected={() => setDeleteConfirmOpen(true)} onPreviewLog={previewGenerationLog} />
|
||||
</Drawer>
|
||||
<Drawer title="参数" placement="bottom" size="default" open={settingsOpen} onClose={() => setSettingsOpen(false)}>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<Drawer title="参数" placement="bottom" height="82vh" open={settingsOpen} onClose={() => setSettingsOpen(false)}>
|
||||
<div className="grid grid-cols-2 gap-3 pb-4">
|
||||
<GenerationSettings config={effectiveConfig} model={model} updateConfig={updateConfig} openConfigDialog={openConfigDialog} />
|
||||
</div>
|
||||
</Drawer>
|
||||
@@ -372,24 +372,17 @@ export default function VideoPage() {
|
||||
}
|
||||
|
||||
function GenerationSettings({ config, model, updateConfig, openConfigDialog }: { config: AiConfig; model: string; updateConfig: UpdateAiConfig; openConfigDialog: (shouldPromptContinue?: boolean) => void }) {
|
||||
const theme = canvasThemes[useThemeStore((state) => state.theme)];
|
||||
|
||||
return (
|
||||
<>
|
||||
<label className="col-span-2 block min-w-0 sm:col-span-1">
|
||||
<span className="mb-1.5 block text-sm font-semibold sm:mb-2 sm:text-base">模型</span>
|
||||
<ModelPicker config={config} value={model} onChange={(value) => updateConfig("videoModel", value)} fullWidth onMissingConfig={() => openConfigDialog(false)} />
|
||||
</label>
|
||||
<label className="block">
|
||||
<span className="mb-1.5 block text-sm font-semibold sm:mb-2 sm:text-base">秒数</span>
|
||||
<AutoComplete className="canvas-control-select w-full" value={config.videoSeconds} options={secondOptions} onChange={(value) => updateConfig("videoSeconds", value)} />
|
||||
</label>
|
||||
<label className="block">
|
||||
<span className="mb-1.5 block text-sm font-semibold sm:mb-2 sm:text-base">尺寸</span>
|
||||
<AutoComplete className="canvas-control-select w-full" value={config.size} options={sizeOptions} placeholder="例如 1280x720" onChange={(value) => updateConfig("size", value)} />
|
||||
</label>
|
||||
<label className="block">
|
||||
<span className="mb-1.5 block text-sm font-semibold sm:mb-2 sm:text-base">清晰度</span>
|
||||
<AutoComplete className="canvas-control-select w-full" value={normalizeResolution(config.vquality)} options={resolutionOptions} placeholder="例如 720" onChange={(value) => updateConfig("vquality", value)} />
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<VideoSettingsPanel config={config} onConfigChange={(key, value) => updateConfig(key, value)} theme={theme} showTitle={false} className="space-y-4" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -582,13 +575,13 @@ function buildVideoConfig(config: AiConfig, model: string): AiConfig {
|
||||
|
||||
function normalizeVideoSeconds(value: string) {
|
||||
const seconds = Math.floor(Number(value) || 6);
|
||||
return String([6, 10, 12, 16, 20].includes(seconds) ? seconds : 6);
|
||||
return String(Math.max(1, Math.min(20, seconds)));
|
||||
}
|
||||
|
||||
function normalizeVideoSize(value: string) {
|
||||
return /^\d+x\d+$/.test(value || "") ? value : "1280x720";
|
||||
return normalizeVideoSizeValue(value);
|
||||
}
|
||||
|
||||
function normalizeResolution(value: string) {
|
||||
return value.replace(/p$/i, "") || "720";
|
||||
return normalizeVideoResolutionValue(value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user