66 lines
3.2 KiB
Rust
66 lines
3.2 KiB
Rust
use super::error::GeneratedAssetSheetError;
|
||
|
||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||
pub struct GeneratedAssetSheetPromptInput<'a> {
|
||
pub subject_text: &'a str,
|
||
pub item_names: &'a [String],
|
||
pub grid_size: usize,
|
||
pub item_name_prompt_template: Option<&'a str>,
|
||
pub special_prompt: Option<&'a str>,
|
||
}
|
||
|
||
pub fn build_generated_asset_sheet_prompt(
|
||
input: &GeneratedAssetSheetPromptInput<'_>,
|
||
) -> Result<String, GeneratedAssetSheetError> {
|
||
let grid_size = input.grid_size;
|
||
if grid_size == 0 {
|
||
return Err(GeneratedAssetSheetError::invalid_request(
|
||
"系列素材图集的 n 必须大于 0。",
|
||
));
|
||
}
|
||
if input.item_names.len() > grid_size {
|
||
return Err(GeneratedAssetSheetError::invalid_request(format!(
|
||
"系列素材图集的物品行数不能超过 n。gridSize={grid_size}, itemCount={}",
|
||
input.item_names.len()
|
||
)));
|
||
}
|
||
|
||
let subject_text = input.subject_text.trim();
|
||
let subject_text = if subject_text.is_empty() {
|
||
"系列素材"
|
||
} else {
|
||
subject_text
|
||
};
|
||
let item_rows = input
|
||
.item_names
|
||
.iter()
|
||
.enumerate()
|
||
.map(|(index, item_name)| {
|
||
let row_index = index + 1;
|
||
let item_name = item_name.trim();
|
||
if let Some(template) = input
|
||
.item_name_prompt_template
|
||
.map(str::trim)
|
||
.filter(|value| !value.is_empty())
|
||
{
|
||
return template
|
||
.replace("{row_index}", row_index.to_string().as_str())
|
||
.replace("{item_name}", item_name)
|
||
.replace("{view_count}", grid_size.to_string().as_str());
|
||
}
|
||
format!("第{row_index}行:{item_name} 的 {grid_size} 个不同视图")
|
||
})
|
||
.collect::<Vec<_>>()
|
||
.join(";");
|
||
let special_prompt = input
|
||
.special_prompt
|
||
.map(str::trim)
|
||
.filter(|value| !value.is_empty())
|
||
.map(str::to_string)
|
||
.unwrap_or_else(|| format!("每个物品生成 {grid_size} 个不同视图。"));
|
||
|
||
Ok(format!(
|
||
"生成一张1:1图片。固定生成{grid_size}行*{grid_size}列网格素材图,画面是{subject_text}。严格{grid_size}*{grid_size}均匀排布,严格按行组织:{item_rows}。{special_prompt}每个格子一个独立居中的完整素材,每格背景必须是统一纯绿色绿幕背景(高饱和亮绿色,接近 #00FF00),背景平整无纹理、无渐变、无阴影、无道具,方便后续抠成透明。素材本身不得使用与绿幕相同的纯绿色;若素材天然含绿色,必须使用更深、更黄或更蓝的绿色并用清晰描边与绿幕区分。统一柔和光照,清晰轮廓,适合直接切割成游戏2D素材。请让每个素材完整落在自己的格子中央,四周保留留白,相邻素材主体之间必须至少保留单个素材格宽度的1/4空白间距(约25%单格宽度),包含左右相邻格和上下相邻行,素材主体不得占满格子。禁止主体跨格、贴边或越界,禁止任何内容进入相邻格子影响裁剪后的效果。不要出现文字、水印、UI、边框、网格线、标签、底座、场景或其他物体。"
|
||
))
|
||
}
|