复用图像下载的共享字节缓冲
将 DownloadedImage.bytes 改为 bytes::Bytes。 让远程下载和图标切片下游避免不必要的完整复制。 同步更新图像处理实现与测试 fixture。
This commit is contained in:
@@ -19064,7 +19064,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn icon_spritesheet_expired_deadline_skips_blocking_image_work() {
|
||||
let source = DownloadedImage {
|
||||
bytes: b"not-an-image".to_vec(),
|
||||
bytes: bytes::Bytes::from_static(b"not-an-image"),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
|
||||
@@ -2324,7 +2324,7 @@ pub async fn split_editor_icon_spritesheet(
|
||||
Err(_) => return Err(editor_icon_spritesheet_processing_timeout_error()),
|
||||
};
|
||||
let source = DownloadedImage {
|
||||
bytes: reference.bytes.to_vec(),
|
||||
bytes: reference.bytes,
|
||||
mime_type: reference.mime_type,
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -2653,7 +2653,7 @@ pub(crate) fn editor_icon_spritesheet_warning_after_persist_error(
|
||||
}
|
||||
|
||||
fn validate_editor_icon_spritesheet_source(source: &DownloadedImage) -> Result<(), AppError> {
|
||||
let reader = image::ImageReader::new(Cursor::new(source.bytes.as_slice()))
|
||||
let reader = image::ImageReader::new(Cursor::new(source.bytes.as_ref()))
|
||||
.with_guessed_format()
|
||||
.map_err(|error| {
|
||||
AppError::from_status(StatusCode::UNPROCESSABLE_ENTITY).with_details(json!({
|
||||
@@ -2931,7 +2931,7 @@ mod tests {
|
||||
.write_to(&mut std::io::Cursor::new(&mut bytes), ImageFormat::Png)
|
||||
.expect("fixture png should encode");
|
||||
let source = DownloadedImage {
|
||||
bytes,
|
||||
bytes: bytes.into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ pub fn slice_generated_asset_sheet(
|
||||
let grid_size_u32 = u32::try_from(grid_size).map_err(|_| {
|
||||
GeneratedAssetSheetError::invalid_request("系列素材图集的 n 超出可支持范围。")
|
||||
})?;
|
||||
let source = image::load_from_memory(image.bytes.as_slice()).map_err(|error| {
|
||||
let source = image::load_from_memory(image.bytes.as_ref()).map_err(|error| {
|
||||
GeneratedAssetSheetError::decode_image(format!("系列素材图集解码失败:{error}"))
|
||||
})?;
|
||||
let source = apply_generated_asset_sheet_green_screen_alpha(source);
|
||||
@@ -94,7 +94,7 @@ pub fn slice_generated_asset_sheet_two_items_per_row(
|
||||
let grid_size_u32 = u32::try_from(grid_size).map_err(|_| {
|
||||
GeneratedAssetSheetError::invalid_request("系列素材图集的 n 超出可支持范围。")
|
||||
})?;
|
||||
let source = image::load_from_memory(image.bytes.as_slice()).map_err(|error| {
|
||||
let source = image::load_from_memory(image.bytes.as_ref()).map_err(|error| {
|
||||
GeneratedAssetSheetError::decode_image(format!("系列素材图集解码失败:{error}"))
|
||||
})?;
|
||||
let source = apply_generated_asset_sheet_green_screen_alpha(source);
|
||||
@@ -243,7 +243,7 @@ pub fn prepare_generated_icon_spritesheet_all_by_connected_components(
|
||||
"图标 spritesheet 累计裁剪像素上限必须大于 0。",
|
||||
));
|
||||
}
|
||||
let source = image::load_from_memory(image.bytes.as_slice()).map_err(|error| {
|
||||
let source = image::load_from_memory(image.bytes.as_ref()).map_err(|error| {
|
||||
GeneratedAssetSheetError::decode_image(format!("图标 spritesheet 解码失败:{error}"))
|
||||
})?;
|
||||
let source = apply_generated_asset_sheet_green_screen_alpha(source);
|
||||
@@ -263,7 +263,7 @@ pub fn prepare_generated_icon_spritesheet_all_by_connected_components(
|
||||
pub fn prepare_generated_icon_spritesheet_grid_2x2(
|
||||
image: &crate::DownloadedImage,
|
||||
) -> Result<GeneratedAssetSheetConnectedIconPlan, GeneratedAssetSheetError> {
|
||||
let source = image::load_from_memory(image.bytes.as_slice()).map_err(|error| {
|
||||
let source = image::load_from_memory(image.bytes.as_ref()).map_err(|error| {
|
||||
GeneratedAssetSheetError::decode_image(format!("图标 spritesheet 解码失败:{error}"))
|
||||
})?;
|
||||
let source = apply_generated_asset_sheet_green_screen_alpha(source).into_rgba8();
|
||||
@@ -942,7 +942,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
}
|
||||
@@ -1031,7 +1031,7 @@ mod tests {
|
||||
sheet.put_pixel(x0 + 40, y0 + 8, Rgba(color));
|
||||
}
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1063,7 +1063,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1095,7 +1095,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1137,7 +1137,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1165,7 +1165,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1206,7 +1206,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1240,7 +1240,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1272,7 +1272,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
@@ -1303,7 +1303,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let source = crate::DownloadedImage {
|
||||
bytes: encode_png(sheet),
|
||||
bytes: encode_png(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
};
|
||||
|
||||
@@ -266,7 +266,7 @@ fn decode_rgba_source(
|
||||
return Err(PixelArtSnapError::InvalidInput(format!("{input} 为空")));
|
||||
}
|
||||
|
||||
let dimension_reader = image::ImageReader::new(Cursor::new(source.bytes.as_slice()))
|
||||
let dimension_reader = image::ImageReader::new(Cursor::new(source.bytes.as_ref()))
|
||||
.with_guessed_format()
|
||||
.map_err(|error| PixelArtSnapError::Decode {
|
||||
input,
|
||||
@@ -281,7 +281,7 @@ fn decode_rgba_source(
|
||||
})?;
|
||||
validate_dimensions(width, height, input)?;
|
||||
|
||||
let mut reader = image::ImageReader::new(Cursor::new(source.bytes.as_slice()))
|
||||
let mut reader = image::ImageReader::new(Cursor::new(source.bytes.as_ref()))
|
||||
.with_guessed_format()
|
||||
.map_err(|error| PixelArtSnapError::Decode {
|
||||
input,
|
||||
@@ -465,7 +465,7 @@ fn encode_png(image: RgbaImage) -> Result<DownloadedImage, PixelArtSnapError> {
|
||||
.write_to(&mut cursor, ImageFormat::Png)
|
||||
.map_err(|error| PixelArtSnapError::Encode(error.to_string()))?;
|
||||
Ok(DownloadedImage {
|
||||
bytes: cursor.into_inner(),
|
||||
bytes: cursor.into_inner().into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
})
|
||||
|
||||
@@ -52,7 +52,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.to_vec(),
|
||||
bytes: body,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ pub(crate) async fn resolve_reference_images(
|
||||
.await
|
||||
.map_err(|error| contextualize_reference_download_error(error, failure_context))?;
|
||||
resolved.push(ReferenceImage {
|
||||
bytes: Bytes::from(downloaded.bytes),
|
||||
bytes: downloaded.bytes,
|
||||
mime_type: downloaded.mime_type.clone(),
|
||||
file_name: format!(
|
||||
"reference-{index}.{}",
|
||||
@@ -248,7 +248,7 @@ pub(crate) fn decode_generated_image_base64(raw: &str) -> Option<DownloadedImage
|
||||
Some(DownloadedImage {
|
||||
extension: mime_to_extension(mime_type.as_str()).to_string(),
|
||||
mime_type,
|
||||
bytes,
|
||||
bytes: bytes.into(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ pub struct RawImageEditResult {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DownloadedImage {
|
||||
pub bytes: Vec<u8>,
|
||||
/// Shared immutable image bytes so callers can pass downloaded buffers downstream without copying.
|
||||
pub bytes: Bytes,
|
||||
pub mime_type: String,
|
||||
pub extension: String,
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ fn build_test_sheet(width: u32, height: u32) -> DownloadedImage {
|
||||
}
|
||||
|
||||
DownloadedImage {
|
||||
bytes: encode_image(sheet),
|
||||
bytes: encode_image(sheet).into(),
|
||||
mime_type: "image/png".to_string(),
|
||||
extension: "png".to_string(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user