feat: use images payload for product suite generation
This commit is contained in:
@@ -14,6 +14,9 @@ from .version import APP_VERSION
|
||||
|
||||
MAX_CMHUB_IMAGE_STUDIO_WORKERS = 5
|
||||
_GLOBAL_IMAGE_STUDIO_SLOTS = threading.BoundedSemaphore(MAX_CMHUB_IMAGE_STUDIO_WORKERS)
|
||||
CMHUB_IMAGE_STUDIO_MAX_INPUT_IMAGES = 8
|
||||
CMHUB_IMAGE_STUDIO_MAX_SINGLE_INPUT_BYTES = 10 * 1024 * 1024
|
||||
CMHUB_IMAGE_STUDIO_MAX_TOTAL_INPUT_BYTES = 32 * 1024 * 1024
|
||||
|
||||
|
||||
class ImageStudioGenerationError(RuntimeError):
|
||||
@@ -50,6 +53,31 @@ def _source_path(source_asset):
|
||||
return path
|
||||
|
||||
|
||||
def _build_cmhub_images(source_asset, reference_assets=()):
|
||||
"""Build the ordered cmhub image input array from local image assets."""
|
||||
candidates = [source_asset] + list(reference_assets or [])
|
||||
selected = candidates[:CMHUB_IMAGE_STUDIO_MAX_INPUT_IMAGES]
|
||||
omitted_count = max(0, len(candidates) - len(selected))
|
||||
images = []
|
||||
total_bytes = 0
|
||||
for index, asset in enumerate(selected, 1):
|
||||
source_path = _source_path(asset)
|
||||
file_size = os.path.getsize(source_path)
|
||||
if file_size > CMHUB_IMAGE_STUDIO_MAX_SINGLE_INPUT_BYTES:
|
||||
role = "主图" if index == 1 else "参考图"
|
||||
raise ImageStudioGenerationError("商品套图%s超过10MiB,不能提交" % role)
|
||||
data_url = ai._image_data_url(source_path)
|
||||
total_bytes += len(data_url.encode("utf-8"))
|
||||
if total_bytes > CMHUB_IMAGE_STUDIO_MAX_TOTAL_INPUT_BYTES:
|
||||
raise ImageStudioGenerationError(
|
||||
"商品套图提交图片总大小超过32MiB,请减少图片或更换较小原图"
|
||||
)
|
||||
images.append({"image_base64": data_url})
|
||||
if not images:
|
||||
raise ImageStudioGenerationError("商品套图至少需要一张本地原图")
|
||||
return images, omitted_count
|
||||
|
||||
|
||||
def create_generation_jobs(
|
||||
project_id,
|
||||
source_asset_id,
|
||||
@@ -324,18 +352,29 @@ def _submit_or_resume_job(
|
||||
db_path,
|
||||
should_stop,
|
||||
on_event,
|
||||
reference_assets=(),
|
||||
):
|
||||
if job.task_id:
|
||||
_notify(on_event, {"job_id": job.id, "step": "cover_request", "result": "resume", "task_id": job.task_id})
|
||||
return _request_result(job.task_id, runtime, config)
|
||||
_raise_if_stopped(should_stop)
|
||||
source_path = _source_path(source_asset)
|
||||
ai_cfg = appconfig.ai_config(config)
|
||||
resolution = str(ai_cfg.get("resolution", "1k") or "1k")
|
||||
images, omitted_count = _build_cmhub_images(source_asset, reference_assets)
|
||||
if omitted_count:
|
||||
_notify(
|
||||
on_event,
|
||||
{
|
||||
"job_id": job.id,
|
||||
"step": "cover_submit",
|
||||
"result": "warning",
|
||||
"detail": "图片最多提交8张,已忽略%d张参考图" % omitted_count,
|
||||
},
|
||||
)
|
||||
payload = {
|
||||
"prompt": str(job.prompt or ""),
|
||||
"model": runtime["alias"],
|
||||
"image_base64": ai._image_data_url(source_path),
|
||||
"images": images,
|
||||
"resolution": ai._normalize_cmhub_resolution(resolution),
|
||||
"aspect_ratio": str(aspect_ratio or "1:1"),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user