From 7edf4a8f8bc12f4516bf968d4a89d097a09649bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sat, 12 Sep 2026 11:06:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E6=97=A7=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E9=93=BE=E8=B7=AF=E5=AD=97=E8=8A=82=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 撤回非 raw_edit 的全局 Bytes 迁移 保留既有 VectorEngine 与编辑器路径的 Vec 字节契约 --- .../crates/api-server/src/editor_project.rs | 25 ++++++------------- .../src/vector_engine/client.rs | 2 +- .../src/vector_engine/constants.rs | 7 ------ .../src/vector_engine/curl_transport.rs | 4 +-- .../src/vector_engine/image_source.rs | 7 +++--- .../src/vector_engine/request.rs | 19 ++++++-------- .../platform-image/src/vector_engine/types.rs | 12 ++------- 7 files changed, 24 insertions(+), 52 deletions(-) diff --git a/server-rs/crates/api-server/src/editor_project.rs b/server-rs/crates/api-server/src/editor_project.rs index c6529863a..b0663a4b1 100644 --- a/server-rs/crates/api-server/src/editor_project.rs +++ b/server-rs/crates/api-server/src/editor_project.rs @@ -19,7 +19,7 @@ use module_assets::{ AssetObjectAccessPolicy, AssetObjectFieldError, AssetObjectUpsertInput, build_asset_object_upsert_input, generate_asset_object_id, }; -use platform_image::{DownloadedImage, GPT_IMAGE_2_2K_LONG_EDGE_THRESHOLD}; +use platform_image::DownloadedImage; use platform_oss::{ LegacyAssetPrefix, OssHeadObjectRequest, OssObjectAccess, OssSignedGetObjectUrlRequest, }; @@ -3841,11 +3841,7 @@ fn editor_image_price_size_from_pixels(size: &str) -> &'static str { let Ok(height) = height.parse::() else { return "1K"; }; - if width.max(height) > GPT_IMAGE_2_2K_LONG_EDGE_THRESHOLD { - "2K" - } else { - "1K" - } + if width.max(height) > 1536 { "2K" } else { "1K" } } fn editor_image_edit_uses_nanobanana_generate_content(model: &str) -> bool { @@ -3894,11 +3890,7 @@ fn infer_editor_image_edit_size_tier(model: &str, size: Option<&str>) -> Option< if model == EDITOR_IMAGE_MODEL_NANOBANANA2 && long_edge <= 768 { return Some("0.5K"); } - Some(if long_edge > GPT_IMAGE_2_2K_LONG_EDGE_THRESHOLD { - "2K" - } else { - "1K" - }) + Some(if long_edge > 1536 { "2K" } else { "1K" }) } fn parse_editor_image_edit_pixel_size(size: &str) -> Option<(u32, u32)> { @@ -4646,7 +4638,7 @@ fn prepare_editor_image_edit_references( ); } for (index, reference) in reference_images.iter_mut().enumerate() { - let decoded = image::load_from_memory(reference.bytes.as_ref()).map_err(|error| { + let decoded = image::load_from_memory(reference.bytes.as_slice()).map_err(|error| { AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({ "provider": "editor-image-edit", "message": format!("图片改造参考图不是有效图片:{error}"), @@ -4677,8 +4669,7 @@ fn prepare_editor_image_edit_references( image::DynamicImage::ImageRgba8(aligned), StatusCode::BAD_REQUEST, "图片改造参考图 16 对齐失败", - )? - .into(); + )?; reference.mime_type = "image/png".to_string(); reference.file_name = format!("editor-image-edit-reference-{}.png", index + 1); } @@ -13522,7 +13513,7 @@ pub(crate) async fn read_editor_reference_image_object_with_client( .to_string(); let extension = editor_reference_image_extension(mime_type.as_str()); Ok(OpenAiReferenceImage { - bytes: bytes.into(), + bytes, mime_type, file_name: format!("editor-reference.{extension}"), }) @@ -13536,7 +13527,7 @@ async fn download_editor_persisted_image_object( Ok(DownloadedOpenAiImage { extension: editor_reference_image_extension(image.mime_type.as_str()).to_string(), mime_type: image.mime_type, - bytes: image.bytes.to_vec(), + bytes: image.bytes, }) } @@ -19064,7 +19055,7 @@ mod tests { #[tokio::test] async fn icon_spritesheet_expired_deadline_skips_blocking_image_work() { let source = DownloadedImage { - bytes: bytes::Bytes::from_static(b"not-an-image"), + bytes: b"not-an-image".to_vec(), mime_type: "image/png".to_string(), extension: "png".to_string(), }; diff --git a/server-rs/crates/platform-image/src/vector_engine/client.rs b/server-rs/crates/platform-image/src/vector_engine/client.rs index 0dbf0be84..24b10196a 100644 --- a/server-rs/crates/platform-image/src/vector_engine/client.rs +++ b/server-rs/crates/platform-image/src/vector_engine/client.rs @@ -1107,7 +1107,7 @@ mod tests { fn reference_image(index: usize) -> ReferenceImage { ReferenceImage { - bytes: bytes::Bytes::from(vec![index as u8]), + bytes: vec![index as u8], mime_type: "image/png".to_string(), file_name: format!("reference-{index}.png"), } diff --git a/server-rs/crates/platform-image/src/vector_engine/constants.rs b/server-rs/crates/platform-image/src/vector_engine/constants.rs index 87572ca73..6480fba73 100644 --- a/server-rs/crates/platform-image/src/vector_engine/constants.rs +++ b/server-rs/crates/platform-image/src/vector_engine/constants.rs @@ -5,10 +5,3 @@ pub const VECTOR_ENGINE_GPT_IMAGE_2_MODEL: &str = GPT_IMAGE_2_MODEL; pub const VECTOR_ENGINE_PROVIDER: &str = "vector-engine"; pub const VECTOR_ENGINE_IMAGE_EDIT_MAX_REFERENCE_IMAGES: usize = 5; pub const VECTOR_ENGINE_NANOBANANA_MAX_REFERENCE_IMAGES: usize = 14; -/// GPT-Image-2 pricing uses 1K through this inclusive long-edge threshold. -pub const GPT_IMAGE_2_2K_LONG_EDGE_THRESHOLD: u32 = 1536; - -pub(crate) const GPT_IMAGE_2_MIN_PIXELS: u64 = 655_360; -pub(crate) const GPT_IMAGE_2_MAX_PIXELS: u64 = 8_294_400; -pub(crate) const GPT_IMAGE_2_MAX_EDGE: u32 = 3_840; -pub(crate) const GPT_IMAGE_2_DIMENSION_ALIGNMENT: u32 = 16; diff --git a/server-rs/crates/platform-image/src/vector_engine/curl_transport.rs b/server-rs/crates/platform-image/src/vector_engine/curl_transport.rs index 0c981f1a6..fbe94e1b1 100644 --- a/server-rs/crates/platform-image/src/vector_engine/curl_transport.rs +++ b/server-rs/crates/platform-image/src/vector_engine/curl_transport.rs @@ -257,7 +257,7 @@ fn send_multipart_edit_request_with_curl_blocking( form.part("image") .buffer( reference_image.file_name.as_str(), - reference_image.bytes.to_vec(), + reference_image.bytes.clone(), ) .content_type(reference_image.mime_type.as_str()) .add()?; @@ -338,7 +338,7 @@ mod tests { "1024x1024", 1, &[ReferenceImage { - bytes: bytes::Bytes::from_static(b"reference"), + bytes: b"reference".to_vec(), mime_type: "image/png".to_string(), file_name: "reference.png".to_string(), }], diff --git a/server-rs/crates/platform-image/src/vector_engine/image_source.rs b/server-rs/crates/platform-image/src/vector_engine/image_source.rs index 7bbe073d4..dbc0b38a4 100644 --- a/server-rs/crates/platform-image/src/vector_engine/image_source.rs +++ b/server-rs/crates/platform-image/src/vector_engine/image_source.rs @@ -1,5 +1,4 @@ use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STANDARD}; -use bytes::Bytes; use reqwest::header; use std::time::Instant; @@ -52,7 +51,7 @@ pub async fn download_remote_image( Ok(DownloadedImage { extension: mime_to_extension(normalized_mime_type.as_str()).to_string(), mime_type: normalized_mime_type, - bytes: body, + bytes: body.to_vec(), }) } @@ -214,7 +213,7 @@ pub(crate) fn parse_reference_image_data_url( })?; let mime_type = normalize_downloaded_image_mime_type(mime_type); Ok(Some(ReferenceImage { - bytes: Bytes::from(bytes), + bytes, file_name: format!( "reference-{index}.{}", mime_to_extension(mime_type.as_str()) @@ -248,7 +247,7 @@ pub(crate) fn decode_generated_image_base64(raw: &str) -> Option String { } fn clamp_gpt_image_2_pixel_size(size: &str) -> String { - const MIN_PIXELS: u64 = GPT_IMAGE_2_MIN_PIXELS; - const MAX_PIXELS: u64 = GPT_IMAGE_2_MAX_PIXELS; - const MAX_EDGE: u32 = GPT_IMAGE_2_MAX_EDGE; - const DIMENSION_ALIGNMENT: u32 = GPT_IMAGE_2_DIMENSION_ALIGNMENT; + const MIN_PIXELS: u64 = 655_360; + const MAX_PIXELS: u64 = 8_294_400; + const MAX_EDGE: u32 = 3_840; + const DIMENSION_ALIGNMENT: u32 = 16; const MAX_ASPECT_RATIO: f64 = 3.0; // 中文注释:这里是 VectorEngine 的共享发送边界,只处理 gpt-image-2 的显式像素尺寸。 @@ -346,12 +343,12 @@ mod tests { 9, &[ ReferenceImage { - bytes: bytes::Bytes::from_static(&[1, 2, 3, 4, 5]), + bytes: vec![1, 2, 3, 4, 5], mime_type: "image/png".to_string(), file_name: "reference-a.png".to_string(), }, ReferenceImage { - bytes: bytes::Bytes::from(vec![8; 7]), + bytes: vec![8; 7], mime_type: "image/jpeg".to_string(), file_name: "reference-b.jpg".to_string(), }, diff --git a/server-rs/crates/platform-image/src/vector_engine/types.rs b/server-rs/crates/platform-image/src/vector_engine/types.rs index 17de6090b..77fbd19f9 100644 --- a/server-rs/crates/platform-image/src/vector_engine/types.rs +++ b/server-rs/crates/platform-image/src/vector_engine/types.rs @@ -1,5 +1,4 @@ use super::audit::PlatformImageFailureAudit; -use bytes::Bytes; #[derive(Clone, Debug)] pub struct VectorEngineImageSettings { @@ -17,23 +16,16 @@ pub struct GeneratedImages { pub recovered_failure_audits: Vec, } -#[derive(Clone, Debug)] -pub struct RawImageEditResult { - pub b64_images: Vec, - pub recovered_failure_audits: Vec, -} - #[derive(Clone, Debug)] pub struct DownloadedImage { - /// Shared immutable image bytes so callers can pass downloaded buffers downstream without copying. - pub bytes: Bytes, + pub bytes: Vec, pub mime_type: String, pub extension: String, } #[derive(Clone, Debug)] pub struct ReferenceImage { - pub bytes: Bytes, + pub bytes: Vec, pub mime_type: String, pub file_name: String, }