update
This commit is contained in:
@@ -3,13 +3,18 @@
|
|||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QRadioButton>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const QString kDefaultFluxInpaintPrompt = QStringLiteral(
|
||||||
|
"这是一幅中国山水画的一部分,mask是被我去除的一个人物,现在需要在原来的位置填充与周围画布连贯的背景");
|
||||||
|
|
||||||
QPushButton* makeAlgoButton(const QString& title, QWidget* parent) {
|
QPushButton* makeAlgoButton(const QString& title, QWidget* parent) {
|
||||||
auto* btn = new QPushButton(parent);
|
auto* btn = new QPushButton(parent);
|
||||||
btn->setCheckable(false);
|
btn->setCheckable(false);
|
||||||
@@ -41,6 +46,13 @@ BlackholeResolveDialog::BlackholeResolveDialog(const QString& blackholeName, QWi
|
|||||||
m_pages->setCurrentWidget(m_pageSelect);
|
m_pages->setCurrentWidget(m_pageSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString BlackholeResolveDialog::inpaintModelKey() const {
|
||||||
|
if (m_radioFlux && m_radioFlux->isChecked()) {
|
||||||
|
return QStringLiteral("flux_fill");
|
||||||
|
}
|
||||||
|
return QStringLiteral("lama");
|
||||||
|
}
|
||||||
|
|
||||||
QString BlackholeResolveDialog::promptText() const {
|
QString BlackholeResolveDialog::promptText() const {
|
||||||
return m_promptEdit ? m_promptEdit->toPlainText().trimmed() : QString();
|
return m_promptEdit ? m_promptEdit->toPlainText().trimmed() : QString();
|
||||||
}
|
}
|
||||||
@@ -104,7 +116,7 @@ void BlackholeResolveDialog::buildDetailPage() {
|
|||||||
auto* pLay = new QVBoxLayout(panel);
|
auto* pLay = new QVBoxLayout(panel);
|
||||||
pLay->setSpacing(8);
|
pLay->setSpacing(8);
|
||||||
|
|
||||||
auto* tip = new QLabel(QStringLiteral("应用后在画布拖取样框。"), panel);
|
auto* tip = new QLabel(QStringLiteral("在画布拖动取样。"), panel);
|
||||||
tip->setStyleSheet("color: palette(mid);");
|
tip->setStyleSheet("color: palette(mid);");
|
||||||
pLay->addWidget(tip);
|
pLay->addWidget(tip);
|
||||||
cLay->addWidget(panel);
|
cLay->addWidget(panel);
|
||||||
@@ -116,13 +128,13 @@ void BlackholeResolveDialog::buildDetailPage() {
|
|||||||
{
|
{
|
||||||
auto* oLay = new QVBoxLayout(m_originalDetail);
|
auto* oLay = new QVBoxLayout(m_originalDetail);
|
||||||
oLay->setSpacing(8);
|
oLay->setSpacing(8);
|
||||||
auto* desc = new QLabel(QStringLiteral("仅隐藏黑洞,不改动背景文件。"), m_originalDetail);
|
auto* desc = new QLabel(QStringLiteral("不修改背景原图。"), m_originalDetail);
|
||||||
desc->setWordWrap(true);
|
desc->setWordWrap(true);
|
||||||
oLay->addWidget(desc);
|
oLay->addWidget(desc);
|
||||||
oLay->addStretch(1);
|
oLay->addStretch(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 详情页 C:模型补全(提示词)
|
// 详情页 C:模型补全
|
||||||
m_modelDetail = new QWidget(m_algoDetails);
|
m_modelDetail = new QWidget(m_algoDetails);
|
||||||
{
|
{
|
||||||
auto* mLay = new QVBoxLayout(m_modelDetail);
|
auto* mLay = new QVBoxLayout(m_modelDetail);
|
||||||
@@ -133,11 +145,49 @@ void BlackholeResolveDialog::buildDetailPage() {
|
|||||||
auto* pLay = new QVBoxLayout(panel);
|
auto* pLay = new QVBoxLayout(panel);
|
||||||
pLay->setSpacing(8);
|
pLay->setSpacing(8);
|
||||||
|
|
||||||
|
m_radioLama = new QRadioButton(QStringLiteral("LaMa"), panel);
|
||||||
|
m_radioFlux = new QRadioButton(QStringLiteral("FLUX Fill"), panel);
|
||||||
|
m_radioLama->setChecked(true);
|
||||||
|
pLay->addWidget(m_radioLama);
|
||||||
|
pLay->addWidget(m_radioFlux);
|
||||||
|
|
||||||
|
m_promptLabel = new QLabel(QStringLiteral("提示词"), panel);
|
||||||
|
pLay->addWidget(m_promptLabel);
|
||||||
|
|
||||||
m_promptEdit = new QPlainTextEdit(panel);
|
m_promptEdit = new QPlainTextEdit(panel);
|
||||||
m_promptEdit->setPlaceholderText(QStringLiteral("可选"));
|
|
||||||
m_promptEdit->setMinimumHeight(72);
|
m_promptEdit->setMinimumHeight(72);
|
||||||
|
m_promptLabel->setVisible(false);
|
||||||
|
m_promptEdit->setVisible(false);
|
||||||
pLay->addWidget(m_promptEdit);
|
pLay->addWidget(m_promptEdit);
|
||||||
|
|
||||||
|
auto syncPromptUi = [this]() {
|
||||||
|
if (!m_promptEdit || !m_promptLabel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bool flux = m_radioFlux && m_radioFlux->isChecked();
|
||||||
|
m_promptLabel->setVisible(flux);
|
||||||
|
m_promptEdit->setVisible(flux);
|
||||||
|
if (flux) {
|
||||||
|
m_promptEdit->setEnabled(true);
|
||||||
|
if (m_promptEdit->toPlainText().trimmed().isEmpty()) {
|
||||||
|
m_promptEdit->setPlainText(kDefaultFluxInpaintPrompt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_promptEdit->setEnabled(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connect(m_radioLama, &QRadioButton::toggled, this, [syncPromptUi](bool on) {
|
||||||
|
if (on) {
|
||||||
|
syncPromptUi();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_radioFlux, &QRadioButton::toggled, this, [syncPromptUi](bool on) {
|
||||||
|
if (on) {
|
||||||
|
syncPromptUi();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
syncPromptUi();
|
||||||
|
|
||||||
mLay->addWidget(panel);
|
mLay->addWidget(panel);
|
||||||
mLay->addStretch(1);
|
mLay->addStretch(1);
|
||||||
}
|
}
|
||||||
@@ -154,7 +204,14 @@ void BlackholeResolveDialog::buildDetailPage() {
|
|||||||
connect(btnBack, &QPushButton::clicked, this, [this]() {
|
connect(btnBack, &QPushButton::clicked, this, [this]() {
|
||||||
m_pages->setCurrentWidget(m_pageSelect);
|
m_pages->setCurrentWidget(m_pageSelect);
|
||||||
});
|
});
|
||||||
connect(btnApply, &QPushButton::clicked, this, &QDialog::accept);
|
connect(btnApply, &QPushButton::clicked, this, [this]() {
|
||||||
|
if (m_selectedAlgorithm == Algorithm::ModelInpaint && m_radioFlux && m_radioFlux->isChecked() &&
|
||||||
|
promptText().isEmpty()) {
|
||||||
|
QMessageBox::warning(this, QStringLiteral("模型补全"), QStringLiteral("请填写提示词。"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
accept();
|
||||||
|
});
|
||||||
connect(btnCancel, &QPushButton::clicked, this, &QDialog::reject);
|
connect(btnCancel, &QPushButton::clicked, this, &QDialog::reject);
|
||||||
layout->addWidget(btns);
|
layout->addWidget(btns);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
class QPlainTextEdit;
|
||||||
|
class QRadioButton;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
|
|
||||||
class BlackholeResolveDialog final : public QDialog {
|
class BlackholeResolveDialog final : public QDialog {
|
||||||
@@ -17,6 +19,8 @@ public:
|
|||||||
explicit BlackholeResolveDialog(const QString& blackholeName, QWidget* parent = nullptr);
|
explicit BlackholeResolveDialog(const QString& blackholeName, QWidget* parent = nullptr);
|
||||||
|
|
||||||
Algorithm selectedAlgorithm() const { return m_selectedAlgorithm; }
|
Algorithm selectedAlgorithm() const { return m_selectedAlgorithm; }
|
||||||
|
QString inpaintModelKey() const;
|
||||||
|
|
||||||
QString promptText() const;
|
QString promptText() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -41,6 +45,9 @@ private:
|
|||||||
QWidget* m_originalDetail = nullptr;
|
QWidget* m_originalDetail = nullptr;
|
||||||
|
|
||||||
QWidget* m_modelDetail = nullptr;
|
QWidget* m_modelDetail = nullptr;
|
||||||
class QPlainTextEdit* m_promptEdit = nullptr;
|
QRadioButton* m_radioLama = nullptr;
|
||||||
|
QRadioButton* m_radioFlux = nullptr;
|
||||||
|
QLabel* m_promptLabel = nullptr;
|
||||||
|
QPlainTextEdit* m_promptEdit = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
#include "dialogs/InpaintPreviewDialog.h"
|
#include "dialogs/InpaintPreviewDialog.h"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QHBoxLayout>
|
#include <QEvent>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QScrollArea>
|
#include <QResizeEvent>
|
||||||
|
#include <QShowEvent>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
|
#include <QTimer>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
static QLabel* makeImageLabel(QWidget* parent) {
|
static QLabel* makeImageLabel(QWidget* parent) {
|
||||||
@@ -14,17 +16,10 @@ static QLabel* makeImageLabel(QWidget* parent) {
|
|||||||
lab->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
lab->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||||
lab->setScaledContents(false);
|
lab->setScaledContents(false);
|
||||||
lab->setAlignment(Qt::AlignCenter);
|
lab->setAlignment(Qt::AlignCenter);
|
||||||
|
lab->setMinimumSize(1, 1);
|
||||||
return lab;
|
return lab;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QScrollArea* wrapScroll(QWidget* child, QWidget* parent) {
|
|
||||||
auto* sc = new QScrollArea(parent);
|
|
||||||
sc->setWidget(child);
|
|
||||||
sc->setWidgetResizable(false);
|
|
||||||
sc->setBackgroundRole(QPalette::Dark);
|
|
||||||
return sc;
|
|
||||||
}
|
|
||||||
|
|
||||||
InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent)
|
InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent)
|
||||||
: QDialog(parent) {
|
: QDialog(parent) {
|
||||||
setModal(true);
|
setModal(true);
|
||||||
@@ -37,14 +32,12 @@ InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent
|
|||||||
|
|
||||||
m_beforeLabel = makeImageLabel(this);
|
m_beforeLabel = makeImageLabel(this);
|
||||||
m_afterLabel = makeImageLabel(this);
|
m_afterLabel = makeImageLabel(this);
|
||||||
m_beforeScroll = wrapScroll(m_beforeLabel, this);
|
m_beforeLabel->installEventFilter(this);
|
||||||
m_afterScroll = wrapScroll(m_afterLabel, this);
|
m_afterLabel->installEventFilter(this);
|
||||||
m_beforeScroll->setMinimumHeight(200);
|
|
||||||
m_afterScroll->setMinimumHeight(200);
|
|
||||||
|
|
||||||
auto* splitter = new QSplitter(Qt::Horizontal, this);
|
auto* splitter = new QSplitter(Qt::Horizontal, this);
|
||||||
splitter->addWidget(m_beforeScroll);
|
splitter->addWidget(m_beforeLabel);
|
||||||
splitter->addWidget(m_afterScroll);
|
splitter->addWidget(m_afterLabel);
|
||||||
splitter->setStretchFactor(0, 1);
|
splitter->setStretchFactor(0, 1);
|
||||||
splitter->setStretchFactor(1, 1);
|
splitter->setStretchFactor(1, 1);
|
||||||
root->addWidget(splitter, 1);
|
root->addWidget(splitter, 1);
|
||||||
@@ -58,17 +51,51 @@ InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InpaintPreviewDialog::setImages(const QImage& before, const QImage& after) {
|
void InpaintPreviewDialog::setImages(const QImage& before, const QImage& after) {
|
||||||
if (m_beforeLabel) {
|
m_beforeImg = before;
|
||||||
const QPixmap pb = QPixmap::fromImage(before);
|
m_afterImg = after;
|
||||||
m_beforeLabel->setPixmap(pb);
|
updateScaledPreviews();
|
||||||
m_beforeLabel->setMinimumSize(pb.size());
|
QTimer::singleShot(0, this, [this]() { updateScaledPreviews(); });
|
||||||
m_beforeLabel->resize(pb.size());
|
|
||||||
}
|
|
||||||
if (m_afterLabel) {
|
|
||||||
const QPixmap pa = QPixmap::fromImage(after);
|
|
||||||
m_afterLabel->setPixmap(pa);
|
|
||||||
m_afterLabel->setMinimumSize(pa.size());
|
|
||||||
m_afterLabel->resize(pa.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InpaintPreviewDialog::resizeEvent(QResizeEvent* e) {
|
||||||
|
QDialog::resizeEvent(e);
|
||||||
|
updateScaledPreviews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InpaintPreviewDialog::showEvent(QShowEvent* e) {
|
||||||
|
QDialog::showEvent(e);
|
||||||
|
updateScaledPreviews();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InpaintPreviewDialog::eventFilter(QObject* watched, QEvent* event) {
|
||||||
|
if (!m_inUpdateScaledPreviews && event->type() == QEvent::Resize) {
|
||||||
|
if (watched == m_beforeLabel || watched == m_afterLabel) {
|
||||||
|
updateScaledPreviews();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QDialog::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InpaintPreviewDialog::updateScaledPreviews() {
|
||||||
|
if (m_inUpdateScaledPreviews) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_inUpdateScaledPreviews = true;
|
||||||
|
auto fit = [](QLabel* lab, const QImage& src) {
|
||||||
|
if (!lab || src.isNull()) {
|
||||||
|
if (lab) {
|
||||||
|
lab->clear();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QSize cap = lab->size();
|
||||||
|
if (cap.width() < 2 || cap.height() < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QImage scaled = src.scaled(cap, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
|
lab->setPixmap(QPixmap::fromImage(scaled));
|
||||||
|
};
|
||||||
|
fit(m_beforeLabel, m_beforeImg);
|
||||||
|
fit(m_afterLabel, m_afterImg);
|
||||||
|
m_inUpdateScaledPreviews = false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
|
||||||
|
class QEvent;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QScrollArea;
|
class QShowEvent;
|
||||||
|
class QResizeEvent;
|
||||||
|
|
||||||
class InpaintPreviewDialog final : public QDialog {
|
class InpaintPreviewDialog final : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -13,10 +15,17 @@ public:
|
|||||||
|
|
||||||
void setImages(const QImage& before, const QImage& after);
|
void setImages(const QImage& before, const QImage& after);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent* e) override;
|
||||||
|
void showEvent(QShowEvent* e) override;
|
||||||
|
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateScaledPreviews();
|
||||||
|
|
||||||
QLabel* m_beforeLabel = nullptr;
|
QLabel* m_beforeLabel = nullptr;
|
||||||
QLabel* m_afterLabel = nullptr;
|
QLabel* m_afterLabel = nullptr;
|
||||||
QScrollArea* m_beforeScroll = nullptr;
|
QImage m_beforeImg;
|
||||||
QScrollArea* m_afterScroll = nullptr;
|
QImage m_afterImg;
|
||||||
|
bool m_inUpdateScaledPreviews = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5006,11 +5006,12 @@ void MainWindow::showBlackholeContextMenu(const QPoint& globalPos, const QString
|
|||||||
client->setBaseUrl(QUrl(base));
|
client->setBaseUrl(QUrl(base));
|
||||||
|
|
||||||
QString immediateErr;
|
QString immediateErr;
|
||||||
|
const QString inpaintModel = dlg.inpaintModelKey();
|
||||||
const QString prompt = dlg.promptText();
|
const QString prompt = dlg.promptText();
|
||||||
QNetworkReply* reply = client->inpaintAsync(
|
QNetworkReply* reply = client->inpaintAsync(
|
||||||
cropPng,
|
cropPng,
|
||||||
maskPng,
|
maskPng,
|
||||||
QStringLiteral("flux_fill"),
|
inpaintModel,
|
||||||
prompt,
|
prompt,
|
||||||
QString(),
|
QString(),
|
||||||
0.72,
|
0.72,
|
||||||
|
|||||||
@@ -7,6 +7,32 @@ import numpy as np
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
|
def _align_spatial_dim_for_flux_fill(n: int, multiple: int = 16) -> int:
|
||||||
|
"""FLUX Fill 要求 H/W 为 (vae_scale_factor*2) 的倍数,常见为 16。"""
|
||||||
|
n = int(max(n, multiple))
|
||||||
|
return n - (n % multiple)
|
||||||
|
|
||||||
|
|
||||||
|
def _flux_clip_prompt_and_t5_full(pipe: Any, text_full: str) -> tuple[str, str]:
|
||||||
|
"""
|
||||||
|
CLIP 仅约 77 token:用与管线一致的 tokenizer 截断得到 prompt(池化向量)。
|
||||||
|
完整文本走 prompt_2 → T5(max_sequence_length 可达 512),长中文不再整段喂给 CLIP。
|
||||||
|
"""
|
||||||
|
text_full = (text_full or "").strip()
|
||||||
|
if not text_full:
|
||||||
|
d = "Chinese ink painting background, natural texture, seamless fill, no figures"
|
||||||
|
return d, d
|
||||||
|
tok = getattr(pipe, "tokenizer", None)
|
||||||
|
if tok is None:
|
||||||
|
return text_full[:120], text_full
|
||||||
|
ml = int(getattr(tok, "model_max_length", 77) or 77)
|
||||||
|
enc = tok([text_full], padding="max_length", max_length=ml, truncation=True, return_tensors="pt")
|
||||||
|
clip_s = tok.batch_decode(enc.input_ids, skip_special_tokens=True)[0].strip()
|
||||||
|
if not clip_s:
|
||||||
|
clip_s = text_full[:80]
|
||||||
|
return clip_s, text_full
|
||||||
|
|
||||||
|
|
||||||
def make_flux_fill_predictor(
|
def make_flux_fill_predictor(
|
||||||
model_id: str,
|
model_id: str,
|
||||||
device: str | None = None,
|
device: str | None = None,
|
||||||
@@ -69,8 +95,8 @@ def make_flux_fill_predictor(
|
|||||||
scale = max_side / float(max(orig_w, orig_h))
|
scale = max_side / float(max(orig_w, orig_h))
|
||||||
run_w = int(round(orig_w * scale))
|
run_w = int(round(orig_w * scale))
|
||||||
run_h = int(round(orig_h * scale))
|
run_h = int(round(orig_h * scale))
|
||||||
run_w = max(8, run_w - (run_w % 8))
|
run_w = _align_spatial_dim_for_flux_fill(run_w)
|
||||||
run_h = max(8, run_h - (run_h % 8))
|
run_h = _align_spatial_dim_for_flux_fill(run_h)
|
||||||
|
|
||||||
if (run_w, run_h) != (orig_w, orig_h):
|
if (run_w, run_h) != (orig_w, orig_h):
|
||||||
image_run = image.resize((run_w, run_h), resample=Image.BICUBIC)
|
image_run = image.resize((run_w, run_h), resample=Image.BICUBIC)
|
||||||
@@ -79,9 +105,10 @@ def make_flux_fill_predictor(
|
|||||||
image_run = image
|
image_run = image
|
||||||
mask_run = mask
|
mask_run = mask
|
||||||
|
|
||||||
p = (prompt or "").strip()
|
p_full = (prompt or "").strip()
|
||||||
if not p:
|
if not p_full:
|
||||||
p = "Chinese ink painting background, natural texture, seamless fill, no figures"
|
p_full = "Chinese ink painting background, natural texture, seamless fill, no figures"
|
||||||
|
p_clip, p_t5 = _flux_clip_prompt_and_t5_full(pipe, p_full)
|
||||||
|
|
||||||
st = float(strength)
|
st = float(strength)
|
||||||
st = min(1.0, max(0.05, st))
|
st = min(1.0, max(0.05, st))
|
||||||
@@ -93,7 +120,8 @@ def make_flux_fill_predictor(
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
out = pipe(
|
out = pipe(
|
||||||
prompt=p,
|
prompt=p_clip,
|
||||||
|
prompt_2=p_t5,
|
||||||
image=image_run,
|
image=image_run,
|
||||||
mask_image=mask_run,
|
mask_image=mask_run,
|
||||||
height=run_h,
|
height=run_h,
|
||||||
|
|||||||
Reference in New Issue
Block a user