optimize image compression conditions and error handling
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
parent
4c98ae337b
commit
5df98f8f05
2 changed files with 73 additions and 69 deletions
|
@ -58,11 +58,13 @@ pub fn postprocess_webp_image(
|
|||
pub fn postprocess_png_image(data: &[u8], opt: &ImageOptions) -> ImageResult<Option<DynamicImage>> {
|
||||
let dec = PngDecoder::new(Cursor::new(data))?;
|
||||
|
||||
if !dec.is_apng()? && opt.requested_resize() {
|
||||
let apng = dec.is_apng()?;
|
||||
|
||||
if !apng && opt.requested_resize() {
|
||||
return Ok(Some(postprocess_static_image(data, opt)?));
|
||||
}
|
||||
|
||||
if opt.static_ == Some(true) {
|
||||
if apng && opt.static_ == Some(true) {
|
||||
let first_frame = match dec.apng()?.into_frames().next() {
|
||||
Some(Ok(frame)) => frame,
|
||||
_ => return Ok(None),
|
||||
|
|
|
@ -18,7 +18,7 @@ use image::{
|
|||
gif::{GifEncoder, Repeat},
|
||||
jpeg::JpegEncoder,
|
||||
},
|
||||
Frames, ImageFormat,
|
||||
Frames, GenericImageView, ImageFormat,
|
||||
};
|
||||
use sniff::SniffingStream;
|
||||
|
||||
|
@ -312,63 +312,63 @@ where
|
|||
ImageFormat::WebP
|
||||
};
|
||||
|
||||
if options.format.is_none() {
|
||||
if mime.starts_with("image/png") || mime.starts_with("image/apng") {
|
||||
let result = sandboxed!(sandbox =>
|
||||
image_processing::postprocess_png_image(&buf, &options)
|
||||
.map_err(|e| {
|
||||
ErrorResponse::postprocess_failed(e.to_string().into())
|
||||
}))?;
|
||||
if mime.starts_with("image/png") || mime.starts_with("image/apng") {
|
||||
let result = sandboxed!(sandbox =>
|
||||
image_processing::postprocess_png_image(&buf, &options)
|
||||
.map_err(|e| {
|
||||
ErrorResponse::postprocess_failed(e.to_string().into())
|
||||
}))?;
|
||||
|
||||
return match result {
|
||||
Some(img) => {
|
||||
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
||||
data: img,
|
||||
format: output_static_format,
|
||||
compression: options.compression_level(),
|
||||
is_https,
|
||||
})
|
||||
.with_timing_info(TIME_TO_FIRST_BYTE_KEY, ttfb)
|
||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
||||
}
|
||||
None => Ok(MediaResponse::Buffer {
|
||||
data: buf,
|
||||
content_type: Some("image/png".into()),
|
||||
}
|
||||
return match result {
|
||||
None => Ok(MediaResponse::Buffer {
|
||||
data: buf,
|
||||
content_type: Some("image/png".into()),
|
||||
}
|
||||
.with_timing_info(TIME_TO_FIRST_BYTE_KEY, ttfb)
|
||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed())),
|
||||
|
||||
Some(img) => {
|
||||
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
||||
data: img,
|
||||
format: output_static_format,
|
||||
compression: options.compression_level(),
|
||||
is_https,
|
||||
})
|
||||
.with_timing_info(TIME_TO_FIRST_BYTE_KEY, ttfb)
|
||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed())),
|
||||
};
|
||||
}
|
||||
if mime.starts_with("image/webp") {
|
||||
let result = sandboxed!(sandbox =>
|
||||
image_processing::postprocess_webp_image(&buf, &options)
|
||||
.map_err(|e| {
|
||||
ErrorResponse::postprocess_failed(e.to_string().into())
|
||||
}))?;
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
||||
}
|
||||
};
|
||||
}
|
||||
if mime.starts_with("image/webp") {
|
||||
let result = sandboxed!(sandbox =>
|
||||
image_processing::postprocess_webp_image(&buf, &options)
|
||||
.map_err(|e| {
|
||||
ErrorResponse::postprocess_failed(e.to_string().into())
|
||||
}))?;
|
||||
|
||||
return match result {
|
||||
Some(img) => {
|
||||
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
||||
data: img,
|
||||
format: output_static_format,
|
||||
compression: options.compression_level(),
|
||||
is_https,
|
||||
})
|
||||
.with_timing_info(TIME_TO_FIRST_BYTE_KEY, ttfb)
|
||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
||||
}
|
||||
None => Ok(MediaResponse::Buffer {
|
||||
data: buf,
|
||||
content_type: Some("image/webp".into()),
|
||||
}
|
||||
return match result {
|
||||
None => Ok(MediaResponse::Buffer {
|
||||
data: buf,
|
||||
content_type: Some("image/webp".into()),
|
||||
}
|
||||
.with_timing_info(TIME_TO_FIRST_BYTE_KEY, ttfb)
|
||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed())),
|
||||
|
||||
Some(img) => {
|
||||
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
||||
data: img,
|
||||
format: output_static_format,
|
||||
compression: options.compression_level(),
|
||||
is_https,
|
||||
})
|
||||
.with_timing_info(TIME_TO_FIRST_BYTE_KEY, ttfb)
|
||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed())),
|
||||
};
|
||||
}
|
||||
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let result = sandboxed!(sandbox => image_processing::postprocess_static_image(
|
||||
|
@ -602,29 +602,31 @@ impl IntoResponse for StaticImage {
|
|||
|
||||
let mut buf = BufWriter::new(Cursor::new(Vec::new()));
|
||||
|
||||
if self.compression == CompressionLevel::None {
|
||||
if self.compression == CompressionLevel::None
|
||||
|| self.data.dimensions().0 * self.data.dimensions().1 <= 256 * 256
|
||||
{
|
||||
self.data.write_to(&mut buf, self.format).unwrap();
|
||||
} else {
|
||||
match self.format {
|
||||
#[cfg(feature = "lossy-webp")]
|
||||
ImageFormat::WebP => {
|
||||
let enc = match webp::Encoder::from_image(&self.data) {
|
||||
Ok(enc) => enc,
|
||||
match webp::Encoder::from_image(&self.data) {
|
||||
Ok(enc) => {
|
||||
let webp = match self.compression {
|
||||
CompressionLevel::Low => enc.encode(80.),
|
||||
CompressionLevel::Med => enc.encode(60.),
|
||||
CompressionLevel::High => enc.encode(40.),
|
||||
CompressionLevel::Max => enc.encode(25.),
|
||||
_ => enc.encode(100.0),
|
||||
};
|
||||
|
||||
buf.write_all(&webp).unwrap();
|
||||
}
|
||||
Err(e) => {
|
||||
return ErrorResponse::postprocess_failed(e.to_string().into())
|
||||
.into_response();
|
||||
log::warn!("webp compression failed: {:?}", e);
|
||||
self.data.write_to(&mut buf, self.format).unwrap();
|
||||
}
|
||||
};
|
||||
|
||||
let webp = match self.compression {
|
||||
CompressionLevel::Low => enc.encode(80.),
|
||||
CompressionLevel::Med => enc.encode(60.),
|
||||
CompressionLevel::High => enc.encode(40.),
|
||||
CompressionLevel::Max => enc.encode(25.),
|
||||
_ => enc.encode(100.0),
|
||||
};
|
||||
|
||||
buf.write_all(&webp).unwrap();
|
||||
}
|
||||
ImageFormat::Jpeg => {
|
||||
let mut enc = JpegEncoder::new_with_quality(
|
||||
|
|
Loading…
Reference in a new issue