diff options
Diffstat (limited to 'src/media.rs')
-rw-r--r-- | src/media.rs | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/src/media.rs b/src/media.rs index 2723816..953dd15 100644 --- a/src/media.rs +++ b/src/media.rs @@ -60,39 +60,16 @@ async fn serve_photo( // Get the payload, at at least 20 MB of it... let data = res.body().limit(20971520).await?; - // Determine the image format - let fmt = image::guess_format(data.as_ref()).map_err(|e| ErrorInternalServerError(e))?; - - // Parse the image - let img = image::load_from_memory_with_format(data.as_ref(), fmt) - .map_err(|e| ErrorInternalServerError(e))?; - - let (orig_width, orig_height) = img.dimensions(); - - let scaled = if width < orig_width && height < orig_height { - // Take the largest size that maintains the aspect ratio - let ratio = orig_width as f64 / orig_height as f64; - let (new_width, new_height) = if width > height { - (width, (width as f64 / ratio) as u32) - } else { - ((height as f64 * ratio) as u32, height) - }; - img.resize(new_width, new_height, FilterType::CatmullRom) - } else { - // We're not going to scale up images. - img - }; - - let mut new_data = Vec::new(); - scaled - .write_to(&mut new_data, fmt) // ImageOutputFormat::Jpeg(128)) + // Resize the image + let (mime, new_data) = web::block(move || scale_image(data.as_ref(), width, height)).await .map_err(|e| ErrorInternalServerError(e))?; + // Send the new image to the client. let mut client_resp = HttpResponse::build(res.status()); client_resp.set(header::CacheControl(vec![header::CacheDirective::MaxAge( 86400u32, )])); - client_resp.set_header(header::CONTENT_TYPE, mime_for_image(fmt)); + client_resp.set_header(header::CONTENT_TYPE, mime); Ok(client_resp.body(new_data)) } @@ -142,6 +119,36 @@ where Ok(client_resp.body(res.body().limit(2147483648).await?)) } +fn scale_image(data: &[u8], width: u32, height: u32) -> Result<(&'static str, Vec<u8>), image::ImageError> { + // Determine the image format + let fmt = image::guess_format(data)?; + + // Parse the image + let img = image::load_from_memory_with_format(data, fmt)?; + + let (orig_width, orig_height) = img.dimensions(); + + let scaled = if width < orig_width && height < orig_height { + // Take the largest size that maintains the aspect ratio + let ratio = orig_width as f64 / orig_height as f64; + let (new_width, new_height) = if width > height { + (width, (width as f64 / ratio) as u32) + } else { + ((height as f64 * ratio) as u32, height) + }; + img.resize(new_width, new_height, FilterType::CatmullRom) + } else { + // We're not going to scale up images. + img + }; + + let mut new_data = Vec::new(); + scaled + .write_to(&mut new_data, fmt)?; // ImageOutputFormat::Jpeg(128)) + + Ok((mime_for_image(fmt), new_data)) +} + fn mime_for_image(fmt: ImageFormat) -> &'static str { match fmt { ImageFormat::Png => "image/png", |