liquid-rescale-api-v2/src/main.rs

84 lines
2.4 KiB
Rust

use std::env::var;
use std::io;
use std::net::SocketAddr;
use std::sync::Once;
use axum::body::Bytes;
use axum::body::Full;
use axum::extract::DefaultBodyLimit;
use axum::extract::Multipart;
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::response::Response;
use axum::routing::get;
use axum::Router;
use magick_rust::magick_wand_genesis;
use magick_rust::MagickWand;
use tower_http::limit::RequestBodyLimitLayer;
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
static START: Once = Once::new();
#[tokio::main]
async fn main() -> io::Result<()> {
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "liquid-rescale-api-v2=debug,tower_http=debug".into()),
)
.with(tracing_subscriber::fmt::layer())
.init();
axum::Server::bind(&SocketAddr::from((
[0, 0, 0, 0],
match var("SERVER_PORT") {
Ok(port) => port.parse::<u16>().unwrap(),
Err(_) => 8321,
},
)))
.serve(
Router::new()
.route("/", get(handle_request))
.layer(DefaultBodyLimit::disable())
.layer(RequestBodyLimitLayer::new(10 * 1024 * 1024 /* 10mb */))
.layer(tower_http::trace::TraceLayer::new_for_http())
.into_make_service(),
)
.await
.unwrap();
Ok(())
}
async fn handle_request(mut payload: Multipart) -> Result<Response<Full<Bytes>>, Response> {
let mut data: Vec<u8> = Vec::new();
while let Some(field) = payload.next_field().await.unwrap() {
let content_type = field.content_type().unwrap();
match content_type {
"image/jpeg" | "image/png" => data = field.bytes().await.unwrap().to_vec(),
_ => return Err(StatusCode::UNSUPPORTED_MEDIA_TYPE.into_response()),
}
}
START.call_once(|| magick_wand_genesis());
let wand = MagickWand::new();
wand.read_image_blob(&data).unwrap();
wand.fit(640, 640);
wand.liquid_rescale_image(320, 320, 1.0, 0.0).unwrap();
wand.fit(640, 640);
let bytes = wand.write_image_blob("JPEG").unwrap();
let body = Full::from(bytes);
Ok(Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "image/jpeg")
.body(Full::from(body))
.unwrap())
}