restore to business size for generate image calls

This commit is contained in:
2026-07-14 20:51:56 +08:00
parent c0bbc1c38d
commit 215c5e0a1f
@@ -1662,6 +1662,9 @@ pub(crate) async fn generate_editor_image_for_owner(
None
};
// TODO the image size passed to api is already normalized, should remove those normalize
// and let resize here to get the proper size
image = restore_editor_generated_image_output_dimensions(image, image_size.as_ref())?;
let (width, height) = image::load_from_memory(image.bytes.as_slice())
.map(|image| (image.width(), image.height()))
.unwrap_or((1024, 1024));
@@ -2219,6 +2222,54 @@ fn restore_editor_image_edit_output_dimensions(
extension: "png".to_string(),
})
}
fn restore_editor_generated_image_output_dimensions(
output: DownloadedOpenAiImage,
// TODO primitive obsession
target_size: &str,
) -> Result<DownloadedOpenAiImage, AppError> {
let (target_width, target_height) = target_size.split_once('x').ok_or_else(|| {
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
"provider": "vector-engine",
"message": "尺寸无效",
}))
})?;
let target_width = target_width.parse::<u32>().map_err(|_| {
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
"provider": "vector-engine",
"message": "宽度无效",
}))
})?;
let target_height = target_height.parse::<u32>().map_err(|_| {
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
"provider": "vector-engine",
"message": "高度无效",
}))
})?;
let decoded = image::load_from_memory(output.bytes.as_slice()).map_err(|error| {
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
"provider": "vector-engine",
"message": format!("素材生成结果不是有效图片:{error}"),
}))
})?;
if decoded.width() == target_width && decoded.height() == target_height {
return Ok(output);
}
let restored = decoded.resize_to_fill(
target_width,
target_height,
image::imageops::FilterType::Lanczos3,
);
Ok(DownloadedOpenAiImage {
bytes: encode_editor_image_edit_png(
restored,
StatusCode::BAD_GATEWAY,
"恢复宣发素材交付尺寸失败",
)?,
mime_type: "image/png".to_string(),
extension: "png".to_string(),
})
}
pub async fn edit_editor_image(
State(state): State<AppState>,
@@ -7497,6 +7548,30 @@ mod tests {
assert_eq!(restored.extension, "png");
}
#[test]
fn publication_material_generation_restores_provider_output_to_workflow_dimensions() {
let image = image::DynamicImage::new_rgba8(944, 704);
let mut bytes = Cursor::new(Vec::new());
image
.write_to(&mut bytes, image::ImageFormat::Png)
.expect("test image should encode");
let restored = restore_editor_generated_image_output_dimensions(
DownloadedOpenAiImage {
bytes: bytes.into_inner(),
mime_type: "image/png".to_string(),
extension: "png".to_string(),
},
"720x540",
)
.expect("provider output should restore delivery dimensions");
let restored_image = image::load_from_memory(restored.bytes.as_slice()).unwrap();
assert_eq!((restored_image.width(), restored_image.height()), (720, 540));
assert_eq!(restored.mime_type, "image/png");
assert_eq!(restored.extension, "png");
}
#[test]
fn editor_generation_dimensions_follow_model_options() {
let default_generation = normalize_editor_generation_options(None, Some("1:1"), Some("1K"));