feat(compress): improve quality guardrails and format conversion

This commit is contained in:
2026-02-08 00:12:27 +08:00
parent f8955d8a6c
commit 65387ca846
8 changed files with 233 additions and 102 deletions

View File

@@ -77,6 +77,22 @@ fn default_units_charged() -> i32 {
1
}
fn ensure_target_size_supported(
target_size_bytes: Option<u64>,
format_out: ImageFmt,
) -> Result<(), AppError> {
if target_size_bytes.is_some() && !compress::supports_target_size_format(format_out) {
return Err(AppError::new(
ErrorCode::InvalidRequest,
format!(
"target_size_bytes 仅支持输出 jpeg/webp/avif当前为 {}",
format_out.as_str()
),
));
}
Ok(())
}
async fn compress_json(
State(state): State<AppState>,
jar: axum_extra::extract::cookie::CookieJar,
@@ -90,15 +106,8 @@ async fn compress_json(
let req = parse_single_file_request(&mut multipart).await?;
let format_in = compress::detect_format(&req.file_bytes)?;
if let Some(format_out) = req.output_format {
if format_out != format_in {
return Err(AppError::new(
ErrorCode::InvalidRequest,
"当前仅支持保持原图片格式",
));
}
}
let format_out = format_in;
let format_out = req.output_format.unwrap_or(format_in);
ensure_target_size_supported(req.target_size_bytes, format_out)?;
let effective_level = req
.compression_rate
.map(compress::rate_to_level)
@@ -407,15 +416,8 @@ async fn compress_direct(
}
let format_in = compress::detect_format(&req.file_bytes)?;
if let Some(format_out) = req.output_format {
if format_out != format_in {
return Err(AppError::new(
ErrorCode::InvalidRequest,
"当前仅支持保持原图片格式",
));
}
}
let format_out = format_in;
let format_out = req.output_format.unwrap_or(format_in);
ensure_target_size_supported(req.target_size_bytes, format_out)?;
let effective_level = req
.compression_rate
.map(compress::rate_to_level)

View File

@@ -540,12 +540,10 @@ async fn parse_batch_request(
opts.level = compress::rate_to_level(rate);
}
if opts.output_format.is_some() {
cleanup_file_paths(&files).await;
return Err(AppError::new(
ErrorCode::InvalidRequest,
"当前仅支持保持原图片格式",
));
if let Some(format_out) = opts.output_format {
for file in &mut files {
file.output_format = format_out;
}
}
let mw = opts.max_width.map(|v| v.to_string()).unwrap_or_default();