faa1ad85ae956e5345022d8dd05cc5d44c02951b
4 use std
::borrow
::BorrowMut
;
6 use num_traits
::cast
::AsPrimitive
;
7 use percent_encoding
::percent_decode_str
;
8 use actix_web
::{get
, web
, App
, HttpServer
, HttpRequest
, HttpResponse
, Responder
, ResponseError
, Result
};
9 use actix_web
::body
::BoxBody
;
10 use actix_web
::http
::StatusCode
;
11 use image
::{ImageBuffer
, ColorType
, Pixel
, Rgb
, RgbImage
, write_buffer_with_format
};
12 use image
::ImageOutputFormat
::Png
;
13 use image
::imageops
::{FilterType
, resize
};
17 struct ImageError(image
::ImageError
);
19 impl Display
for ImageError
{
20 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
21 write
!(f
, "{}", &self.0)
25 impl ResponseError
for ImageError
{
26 fn status_code(&self) -> StatusCode
{
27 StatusCode
::INTERNAL_SERVER_ERROR
30 fn error_response(&self) -> HttpResponse
<BoxBody
> {
31 HttpResponse
::InternalServerError().fin
ish
()
35 struct ToRgbIter
<'a
, T
> where T
: AsPrimitive
<u8> {
36 iter
: Box
<&'a
mut dyn Iterator
<Item
= T
>>
39 impl<'a
, T
: AsPrimitive
<u8>> ToRgbIter
<'a
, T
> {
40 fn new(data
: &'a
mut (dyn Iterator
<Item
= T
>)) -> ToRgbIter
<T
> {
41 ToRgbIter
{ iter
: Box
::new(data
) }
45 impl<T
: AsPrimitive
<u8> + Zero
> Iterator
for ToRgbIter
<'_
, T
> {
47 fn next(&mut self) -> Option
<Rgb
<u8>> {
48 if let Some(r
) = self.iter
.next() {
49 let g
= self.iter
.next().unwrap
_or
(T
::zero());
50 let b
= self.iter
.next().unwrap
_or
(T
::zero());
51 println
!("{} {} {}", r
.as_(), g
.as_(), b
.as_());
52 Some(Rgb([r
.as_(), g
.as_(), b
.as_()]))
60 fn to_imageresult
<T
> (result
: Result
<T
, image
::ImageError
>) -> Result
<T
, ImageError
> {
63 Err(e
) => Err(ImageError(e
))
67 #[get("/hello/{name}")]
68 async
fn greet(name
: web
::Path
<String
>, req
: HttpRequest
) -> impl Responder
{
69 println
!("{:?}", req
);
70 format
!("Hello {name}!")
73 fn make_png(dim_x
: u32, dim_y
: u32, scale
: u32, data
: &str) -> Result
<Cursor
<Vec
<u8>>, ImageError
> {
74 let mut img
: RgbImage
= ImageBuffer
::new(dim_x
, dim_y
);
75 let mut pixels
= img
.pixels_mut();
77 for sp
in ToRgbIter
::new(percent_decode_str(&data
).into
_iter
().borrow_mut()) {
78 let mut dp
= pixels
.next().unwrap
();
83 let tdim_x
= dim_x
* scale
;
84 let tdim_y
= dim_y
* scale
;
85 let img
= resize(&img
, tdim_x
, tdim_y
, FilterType
::Nearest
);
86 let mut cursor
= Cursor
::new(Vec
::new());
87 to_imageresult(write_buffer_with_format(&mut cursor
, &img
, tdim_x
, tdim_y
, ColorType
::Rgb8
, Png
))?
;
91 #[get("/gen/0/{data}")]
92 async
fn img_gen0(req
: HttpRequest
) -> Result
<impl Responder
> {
93 let data
= req
.ur
i().path().split("/").skip(3).next().unwrap
();
94 let cursor
= make_png(32, 32, 16, &data
)?
;
95 Ok(HttpResponse
::build(StatusCode
::OK
)
96 .content_type("image/png")
97 .body(cursor
.into
_inner
()))
100 #[get("/gen/1/{dim_x}/{dim_y}/{scale}/{data}")]
101 async
fn img_gen1(req
: HttpRequest
, dim_x
: web
::Path
<u16>, dim_y
: web
::Path
<u16>, scale
: web
::Path
<u8>) -> Result
<impl Responder
> {
102 Ok(HttpResponse
::build(StatusCode
::OK
))
105 #[actix_web::main] // or #[tokio::main]
106 async
fn main() -> std
::io
::Result
<()> {
113 .bind(("127.0.0.1", 8080))?