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

78 lines
2.1 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::Response;
use axum::routing::post;
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("/", post(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() {
data = field.bytes().await.unwrap().to_vec();
}
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())
}