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>> {
|
pub fn postprocess_png_image(data: &[u8], opt: &ImageOptions) -> ImageResult<Option<DynamicImage>> {
|
||||||
let dec = PngDecoder::new(Cursor::new(data))?;
|
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)?));
|
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() {
|
let first_frame = match dec.apng()?.into_frames().next() {
|
||||||
Some(Ok(frame)) => frame,
|
Some(Ok(frame)) => frame,
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
|
|
|
@ -18,7 +18,7 @@ use image::{
|
||||||
gif::{GifEncoder, Repeat},
|
gif::{GifEncoder, Repeat},
|
||||||
jpeg::JpegEncoder,
|
jpeg::JpegEncoder,
|
||||||
},
|
},
|
||||||
Frames, ImageFormat,
|
Frames, GenericImageView, ImageFormat,
|
||||||
};
|
};
|
||||||
use sniff::SniffingStream;
|
use sniff::SniffingStream;
|
||||||
|
|
||||||
|
@ -312,7 +312,6 @@ where
|
||||||
ImageFormat::WebP
|
ImageFormat::WebP
|
||||||
};
|
};
|
||||||
|
|
||||||
if options.format.is_none() {
|
|
||||||
if mime.starts_with("image/png") || mime.starts_with("image/apng") {
|
if mime.starts_with("image/png") || mime.starts_with("image/apng") {
|
||||||
let result = sandboxed!(sandbox =>
|
let result = sandboxed!(sandbox =>
|
||||||
image_processing::postprocess_png_image(&buf, &options)
|
image_processing::postprocess_png_image(&buf, &options)
|
||||||
|
@ -321,6 +320,14 @@ where
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
return match result {
|
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) => {
|
Some(img) => {
|
||||||
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
||||||
data: img,
|
data: img,
|
||||||
|
@ -332,13 +339,6 @@ where
|
||||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||||
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
||||||
}
|
}
|
||||||
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())),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if mime.starts_with("image/webp") {
|
if mime.starts_with("image/webp") {
|
||||||
|
@ -349,6 +349,14 @@ where
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
return match result {
|
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) => {
|
Some(img) => {
|
||||||
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
Ok(MediaResponse::ProcessedStaticImage(StaticImage {
|
||||||
data: img,
|
data: img,
|
||||||
|
@ -360,16 +368,8 @@ where
|
||||||
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
.with_opt_timing_info(SLURP_TIMING_KEY, Some(slurp_dur))
|
||||||
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
.with_timing_info(TIMING_KEY, begin.elapsed()))
|
||||||
}
|
}
|
||||||
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())),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let result = sandboxed!(sandbox => image_processing::postprocess_static_image(
|
let result = sandboxed!(sandbox => image_processing::postprocess_static_image(
|
||||||
&buf, &options
|
&buf, &options
|
||||||
|
@ -602,20 +602,16 @@ impl IntoResponse for StaticImage {
|
||||||
|
|
||||||
let mut buf = BufWriter::new(Cursor::new(Vec::new()));
|
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();
|
self.data.write_to(&mut buf, self.format).unwrap();
|
||||||
} else {
|
} else {
|
||||||
match self.format {
|
match self.format {
|
||||||
#[cfg(feature = "lossy-webp")]
|
#[cfg(feature = "lossy-webp")]
|
||||||
ImageFormat::WebP => {
|
ImageFormat::WebP => {
|
||||||
let enc = match webp::Encoder::from_image(&self.data) {
|
match webp::Encoder::from_image(&self.data) {
|
||||||
Ok(enc) => enc,
|
Ok(enc) => {
|
||||||
Err(e) => {
|
|
||||||
return ErrorResponse::postprocess_failed(e.to_string().into())
|
|
||||||
.into_response();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let webp = match self.compression {
|
let webp = match self.compression {
|
||||||
CompressionLevel::Low => enc.encode(80.),
|
CompressionLevel::Low => enc.encode(80.),
|
||||||
CompressionLevel::Med => enc.encode(60.),
|
CompressionLevel::Med => enc.encode(60.),
|
||||||
|
@ -626,6 +622,12 @@ impl IntoResponse for StaticImage {
|
||||||
|
|
||||||
buf.write_all(&webp).unwrap();
|
buf.write_all(&webp).unwrap();
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("webp compression failed: {:?}", e);
|
||||||
|
self.data.write_to(&mut buf, self.format).unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
ImageFormat::Jpeg => {
|
ImageFormat::Jpeg => {
|
||||||
let mut enc = JpegEncoder::new_with_quality(
|
let mut enc = JpegEncoder::new_with_quality(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
|
|
Loading…
Reference in a new issue