A photo manager for VRChat.
1use fast_image_resize::{images::Image, IntoImageView, ResizeOptions, Resizer};
2use image::{
3 codecs::png::{PngDecoder, PngEncoder},
4 DynamicImage, ImageEncoder,
5};
6use std::{
7 fs,
8 io::{BufReader, Read},
9 thread,
10};
11use tauri::{
12 http::{Request, Response}, State, UriSchemeResponder
13};
14
15use super::cache::Cache;
16
17pub fn handle_uri_proto( request: Request<Vec<u8>>, responder: UriSchemeResponder, cache: State<Cache> ) {
18 let photo_path = cache.get("photo-path".into());
19
20 thread::spawn(move || {
21 // Loads the requested image file, sends data back to the user
22 let uri = request.uri();
23
24 if request.method() != "GET" {
25 responder.respond(
26 Response::builder()
27 .status(404)
28 .header("Access-Control-Allow-Origin", "*")
29 .body(Vec::new())
30 .unwrap(),
31 );
32
33 return;
34 }
35
36 #[cfg(windows)]
37 let path = uri.path().split_at(1).1;
38
39 #[cfg(unix)]
40 let path = uri.path();
41
42 let path = format!("{}/{}", photo_path.unwrap(), path);
43 let file = fs::File::open(path);
44
45 match file {
46 Ok(mut file) => match uri.query().unwrap() {
47 "downscale" => {
48 let decoder = PngDecoder::new(BufReader::new(&file)).unwrap();
49 let src_image = DynamicImage::from_decoder(decoder).unwrap();
50
51 let size_multiplier: f32 = 200.0 / src_image.height() as f32;
52
53 let dst_width = (src_image.width() as f32 * size_multiplier).floor() as u32;
54 let dst_height: u32 = 200;
55
56 let mut dst_image = Image::new(dst_width, dst_height, src_image.pixel_type().unwrap());
57 let mut resizer = Resizer::new();
58
59 let opts = ResizeOptions::new().resize_alg(fast_image_resize::ResizeAlg::Convolution(fast_image_resize::FilterType::Bilinear));
60
61 resizer
62 .resize(&src_image, &mut dst_image, Some(&opts))
63 .unwrap();
64
65 let mut buf = Vec::new();
66 let encoder = PngEncoder::new(&mut buf);
67
68 encoder
69 .write_image(
70 dst_image.buffer(),
71 dst_width,
72 dst_height,
73 src_image.color().into(),
74 )
75 .unwrap();
76
77 let res = Response::builder()
78 .status(200)
79 .header("Access-Control-Allow-Origin", "*")
80 .body(buf)
81 .unwrap();
82
83 responder.respond(res);
84 }
85 _ => {
86 let mut buf = Vec::new();
87 file.read_to_end(&mut buf).unwrap();
88
89 let res = Response::builder()
90 .status(200)
91 .header("Access-Control-Allow-Origin", "*")
92 .body(buf)
93 .unwrap();
94
95 responder.respond(res);
96 }
97 },
98 Err(_) => {
99 responder.respond(
100 Response::builder()
101 .status(404)
102 .header("Access-Control-Allow-Origin", "*")
103 .body(b"File Not Found")
104 .unwrap(),
105 );
106 }
107 }
108 });
109}