diff --git a/examples/upscaling.rs b/examples/upscaling.rs new file mode 100644 index 00000000..3d022fea --- /dev/null +++ b/examples/upscaling.rs @@ -0,0 +1,17 @@ +use macroquad::prelude::*; + +#[macroquad::main("Upscaling")] +async fn main() { + let texture: Texture2D = load_texture("examples/rustacean_happy.png").await.unwrap(); + let double = Texture2D::from_image(&texture.get_texture_data().upscale(2)); + let triple = Texture2D::from_image(&texture.get_texture_data().upscale(3)); + + loop { + clear_background(LIGHTGRAY); + draw_texture(&texture, 40., 40., WHITE); + draw_texture(&double, 140., 140., WHITE); + draw_texture(&triple, 240., 240., WHITE); + + next_frame().await + } +} diff --git a/src/texture.rs b/src/texture.rs index c31c3e66..6ee3c50e 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -323,6 +323,38 @@ impl Image { ) .unwrap(); } + + /// Scales an image up by the given factor `n`. + /// Returns the new image. + pub fn upscale(&self, n: u16) -> Self { + let mut new_bytes = vec![]; + let mut current_line_length = 0; + + for pixel in self.get_image_data() { + // repeat n times horizontally + for _ in 0..n { + new_bytes.extend_from_slice(pixel); + } + current_line_length += 1; + + if current_line_length == self.width { + // repeat n - 1 times vertically, because one line already exists + let last_line = new_bytes + [(new_bytes.len() - (4 * self.width() * n as usize))..new_bytes.len()] + .to_vec(); + for _ in 0..n - 1 { + new_bytes.extend_from_slice(&last_line); + } + current_line_length = 0; + } + } + + Self { + width: self.width * n, + height: self.height * n, + bytes: new_bytes, + } + } } /// Loads an [Image] from a file into CPU memory.