支持分离流程转换非 PNG 源图
在上传图片编辑请求前将 JPEG 和 WebP 转码为 PNG 新增 JPEG 转 PNG 单元测试并将转码放入阻塞任务
This commit is contained in:
+37
-3
@@ -54,15 +54,20 @@ async fn raw_extract_inner(
|
||||
.strip_prefix("data:")
|
||||
.and_then(|value| value.strip_suffix(";base64"))
|
||||
.unwrap_or("image/png");
|
||||
if !mime.eq_ignore_ascii_case("image/png") {
|
||||
return Err("图片分离请求只支持 PNG 源图".to_string());
|
||||
}
|
||||
let is_png = mime.eq_ignore_ascii_case("image/png");
|
||||
let image_bytes = base64::engine::general_purpose::STANDARD
|
||||
.decode(data.trim())
|
||||
.map_err(|error| format!("解码源图失败:{error}"))?;
|
||||
if image_bytes.is_empty() {
|
||||
return Err("源图不能为空".to_string());
|
||||
}
|
||||
let image_bytes = if is_png {
|
||||
image_bytes
|
||||
} else {
|
||||
tokio::task::spawn_blocking(move || normalize_source_image_to_png(image_bytes))
|
||||
.await
|
||||
.map_err(|error| format!("转换源图任务失败:{error}"))??
|
||||
};
|
||||
let client = crate::http_client::agc_main_site_client_builder()
|
||||
.build()
|
||||
.map_err(|error| format!("创建图片编辑客户端失败:{error}"))?;
|
||||
@@ -122,6 +127,35 @@ async fn raw_extract_inner(
|
||||
result
|
||||
}
|
||||
|
||||
fn normalize_source_image_to_png(image_bytes: Vec<u8>) -> Result<Vec<u8>, String> {
|
||||
let image = image::load_from_memory(&image_bytes)
|
||||
.map_err(|error| format!("解码非 PNG 源图失败:{error}"))?;
|
||||
let mut png_bytes = Vec::new();
|
||||
image
|
||||
.write_to(&mut Cursor::new(&mut png_bytes), image::ImageFormat::Png)
|
||||
.map_err(|error| format!("将源图转换为 PNG 失败:{error}"))?;
|
||||
Ok(png_bytes)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::normalize_source_image_to_png;
|
||||
use image::{DynamicImage, ImageFormat, Rgb, RgbImage};
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
fn converts_jpeg_source_to_png() {
|
||||
let image = DynamicImage::ImageRgb8(RgbImage::from_pixel(2, 2, Rgb([255, 0, 0])));
|
||||
let mut jpeg = Vec::new();
|
||||
image
|
||||
.write_to(&mut Cursor::new(&mut jpeg), ImageFormat::Jpeg)
|
||||
.expect("encode jpeg");
|
||||
|
||||
let png = normalize_source_image_to_png(jpeg).expect("convert jpeg");
|
||||
assert_eq!(&png[..8], b"\x89PNG\r\n\x1a\n");
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) async fn write_processed_image(
|
||||
processed_url: String,
|
||||
target: PathBuf,
|
||||
|
||||
Reference in New Issue
Block a user