use std::fmt::Display;
use std::fmt;
use std::borrow::BorrowMut;
+use std::sync::{Arc, Mutex};
use num_traits::Zero;
use num_traits::cast::AsPrimitive;
use percent_encoding::percent_decode_str;
}
}
+struct Canvas {
+ pen: usize,
+ img: RgbImage
+}
+
+impl Canvas {
+ fn new(width: u32, height: u32) -> Canvas {
+ Canvas { pen: 0, img: ImageBuffer::new(width, height) }
+ }
+
+ fn from_image(img: RgbImage) -> Canvas {
+ Canvas { pen: 0, img }
+ }
+
+ /*fn replace(&self, img: RgbImage, pen: usize) -> Canvas {
+ self.img = img;
+ self.pen = pen;
+ self
+ }*/
+
+ fn advance_pen(mut self, offset: usize) -> Canvas {
+ //Canvas { pen: self.pen + offset, img: self.img }
+ self.pen += offset;
+ self
+ }
+}
+
#[get("/hello/{name}")]
async fn greet(name: web::Path<String>, req: HttpRequest) -> impl Responder {
println!("{:?}", req);
format!("Hello {name}!")
}
-fn make_png(dim_x: u32, dim_y: u32, scale: u32, data: &mut dyn Iterator<Item = u8>) -> Result<Cursor<Vec<u8>>, ImageError> {
- // Image must not be larger than 1 megapixel
- if dim_x * dim_y * scale > 1048576 {
- return Err(ImageError::dimension_error())
- }
-
- let mut img: RgbImage = ImageBuffer::new(dim_x, dim_y);
- let mut pixels = img.pixels_mut();
+fn rgb_encode_to_canvas(mut canvas: Canvas, data: &mut dyn Iterator<Item = u8>) -> Result<Canvas, ImageError> {
+ let mut pixels = canvas.img.pixels_mut().skip(canvas.pen);
+ let mut counter = 0;
for sp in ToRgbIter::new(data) {
let mut dp = pixels.next().ok_or(ImageError::dimension_error())?;
println!("{:?}", sp);
dp.0 = sp.0;
+ counter += 1;
}
+ Ok(canvas.advance_pen(counter))
+}
+
+fn rgb_encode(img: RgbImage, data: &mut dyn Iterator<Item = u8>) -> Result<RgbImage, ImageError> {
+ Ok(rgb_encode_to_canvas(Canvas::from_image(img), data)?.img)
+}
+
+fn make_png(dim_x: u32, dim_y: u32, scale: u32, data: &mut dyn Iterator<Item = u8>) -> Result<Cursor<Vec<u8>>, ImageError> {
+ // Image must not be larger than 1 megapixel
+ if dim_x * dim_y * scale > 1048576 {
+ return Err(ImageError::dimension_error())
+ }
+
+ let mut img: RgbImage = rgb_encode(ImageBuffer::new(dim_x, dim_y), data)?;
+
let tdim_x = dim_x * scale;
let tdim_y = dim_y * scale;
let img = resize(&img, tdim_x, tdim_y, FilterType::Nearest);
async fn img_gen0(req: HttpRequest) -> Result<impl Responder> {
let data = req.uri().path().split("/").skip(3).next().unwrap();
let cursor = make_png(32, 32, 16, percent_decode_str(&data).into_iter().borrow_mut())?;
+ println!("{:?}", &cursor);
Ok(HttpResponse::build(StatusCode::OK)
.content_type("image/png")
.body(cursor.into_inner()))
.body(cursor.into_inner()))
}
+#[get("/pgen/0/{data}")]
+async fn img_pgen0(req: HttpRequest, canvas0: web::Data<Arc<Mutex<Option<Canvas>>>>) -> Result<impl Responder> {
+ let data = req.uri().path().split("/").skip(3).next().unwrap();
+ let mut cursor = Cursor::new(Vec::new());
+ let tdim_x = 32;
+ let tdim_y = 32;
+ {
+ let mut canvas_option = &mut *canvas0.lock().unwrap();
+ let canvas = canvas_option.take();
+ let canvas = rgb_encode_to_canvas(canvas.expect("Canvas doesn't exist!"), percent_decode_str(&data).into_iter().borrow_mut())?;
+ to_imageresult(write_buffer_with_format(&mut cursor, &canvas.img, tdim_x, tdim_y, ColorType::Rgb8, Png))?;
+ canvas_option.insert(canvas);
+ }
+ Ok(HttpResponse::build(StatusCode::OK)
+ .content_type("image/png")
+ .body(cursor.into_inner()))
+}
+
#[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> {
env_logger::init();
- HttpServer::new(|| {
+ let canvas0 = Arc::new(Mutex::new(Some(Canvas::new(32, 32))));
+ HttpServer::new(move || {
App::new()
.service(greet)
.service(img_gen0)
.service(img_gen1)
+ .service(img_pgen0)
+ .app_data(web::Data::new(canvas0.clone()))
})
.bind(("127.0.0.1", 8080))?
.run()