84 lines
2.4 KiB
Rust
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::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() {
|
|
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())
|
|
}
|