Add optional reference photo conditioning to Flux generation
This commit is contained in:
+9
-8
@@ -182,9 +182,9 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="studioMode === 'edit' || (studioMode === 'editv2' && (v2Mode === 'compose' || (v2Mode === 'iterate' && file)))" class="rounded-2xl border border-dashed border-white/15 bg-zinc-950/50 p-4">
|
||||
<div v-if="fluxTextReference || studioMode === 'edit' || (studioMode === 'editv2' && (v2Mode === 'compose' || (v2Mode === 'iterate' && file)))" class="rounded-2xl border border-dashed border-white/15 bg-zinc-950/50 p-4">
|
||||
<div class="mb-2 flex items-center justify-between gap-2">
|
||||
<p class="text-sm font-medium text-zinc-300">{{ studioMode === 'editv2' && v2Mode === 'compose' ? 'Still B · required' : studioMode === 'editv2' ? 'Still B · optional' : 'Image 2 · optional' }}</p>
|
||||
<p class="text-sm font-medium text-zinc-300">{{ fluxTextReference ? 'Reference photo · optional' : studioMode === 'editv2' && v2Mode === 'compose' ? 'Still B · required' : studioMode === 'editv2' ? 'Still B · optional' : 'Image 2 · optional' }}</p>
|
||||
<button
|
||||
v-if="editRefFile"
|
||||
type="button"
|
||||
@@ -213,11 +213,11 @@
|
||||
class="max-h-40 w-full object-contain bg-black/40"
|
||||
>
|
||||
<span v-else class="flex min-h-28 items-center justify-center px-3 py-6 text-center text-sm text-zinc-500">
|
||||
{{ studioMode === 'editv2' ? stillBHint : 'Apply this still onto image 1' }}
|
||||
{{ fluxTextReference ? 'Choose a reference photo from your library or upload one' : studioMode === 'editv2' ? stillBHint : 'Apply this still onto image 1' }}
|
||||
</span>
|
||||
</button>
|
||||
<p class="mt-2 text-xs text-zinc-500">
|
||||
{{ studioMode === 'editv2'
|
||||
{{ fluxTextReference ? 'Guides a new image from your text. This is not a starting image; your selected output size stays in effect. Describe which details to use from the photo.' : studioMode === 'editv2'
|
||||
? (editRefFile ? stillBHint : 'Compose will reject this job until still B is loaded.')
|
||||
: (editRefFile
|
||||
? 'Two-image branch on. Image 2 is applied onto image 1.'
|
||||
@@ -2716,6 +2716,7 @@ const v2Mode = computed<ImageV2Mode>({
|
||||
set: mode => { selectedV2Mode.value = mode }
|
||||
})
|
||||
const v2Engine = ref<ImageV2Engine>('flux')
|
||||
const fluxTextReference = computed(() => studioMode.value === 'editv2' && v2Engine.value === 'flux' && (v2Mode.value === 'generate' || (v2Mode.value === 'iterate' && !file.value)))
|
||||
const v2Task = ref<ImageV2Task>('scene')
|
||||
const v2Negative = ref('')
|
||||
const v2Steps = ref(IMAGE_V2_STEPS_DEFAULT)
|
||||
@@ -2923,7 +2924,7 @@ const REFS_STORE = 'aigen-permanence-refs'
|
||||
const pickerHeading = computed(() => {
|
||||
if (pickerKind.value === 'permanence') return 'Choose a still to name'
|
||||
if (pickerSlot.value === 'main') return studioMode.value === 'edit' || studioMode.value === 'editv2' ? (studioMode.value === 'editv2' ? 'Choose still A' : 'Choose image 1') : 'Choose an image'
|
||||
if (pickerSlot.value === 'editRef') return studioMode.value === 'editv2' ? 'Choose still B' : 'Choose image 2'
|
||||
if (pickerSlot.value === 'editRef') return fluxTextReference.value ? 'Choose a reference photo' : studioMode.value === 'editv2' ? 'Choose still B' : 'Choose image 2'
|
||||
return `Choose Picture ${Number(pickerSlot.value) + 2}`
|
||||
})
|
||||
const permanencePicker = computed(() => pickerKind.value === 'permanence')
|
||||
@@ -5552,7 +5553,7 @@ async function restoreStudioEditJob(payload: {
|
||||
if (payload.hideInput && showPrivacyToggles.value) hideInputPreview.value = true
|
||||
readFile(new File([blob], stillFileName(stills.value.find(item => item.id === payload.stillId)) || payload.stillFilename || 'still.png', { type: blob.type || 'image/png' }), { stillId: payload.stillId })
|
||||
}
|
||||
if (v2 && payload.v2Mode === 'compose' && payload.referenceStillId) {
|
||||
if (v2 && ['compose', 'generate', 'iterate'].includes(payload.v2Mode || '') && payload.referenceStillId) {
|
||||
await loadStillAsEditRef(payload.referenceStillId).catch(() => null)
|
||||
} else if (!(v2 && payload.v2Mode === 'compose')) {
|
||||
clearEditRef()
|
||||
@@ -6472,7 +6473,7 @@ async function useStillAsInput(still: LibraryStill) {
|
||||
const blob = await $fetch<Blob>(`/api/library/stills/${still.id}`, { responseType: 'blob' })
|
||||
if (still.hideInput && showPrivacyToggles.value) hideInputPreview.value = true
|
||||
readFile(new File([blob], stillFileName(still), { type: blob.type || 'image/png' }), { stillId: still.id })
|
||||
if (dest === 'imagev2' && still.settings?.mode === 'compose' && still.settings.referenceStillId) {
|
||||
if (dest === 'imagev2' && ['compose', 'generate', 'iterate'].includes(still.settings?.mode || '') && still.settings?.referenceStillId) {
|
||||
try {
|
||||
await loadStillAsEditRef(still.settings.referenceStillId)
|
||||
} catch {
|
||||
@@ -7316,7 +7317,7 @@ async function editImageV2() {
|
||||
? v2Task.value
|
||||
: 'scene')
|
||||
if (v2Mode.value !== 'generate' && file.value) body.append('image_a', file.value)
|
||||
if ((v2Mode.value === 'compose' || v2Mode.value === 'iterate') && editRefFile.value) body.append('image_b', editRefFile.value)
|
||||
if ((fluxTextReference.value || v2Mode.value === 'compose' || v2Mode.value === 'iterate') && editRefFile.value) body.append('image_b', editRefFile.value)
|
||||
if (v2Mode.value === 'refine' || (v2Engine.value === 'krea' && v2Mode.value !== 'generate' && !iterateGenerate)) {
|
||||
if (v2Mode.value === 'refine') {
|
||||
const maskBlob = await refinePainter.value?.exportPng()
|
||||
|
||||
Reference in New Issue
Block a user