Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image example #48

Closed
aeosynth opened this issue Feb 2, 2018 · 5 comments
Closed

image example #48

aeosynth opened this issue Feb 2, 2018 · 5 comments

Comments

@aeosynth
Copy link

aeosynth commented Feb 2, 2018

can we have an example showing how to display an image (say, the rust logo) with this library?

@tversteeg
Copy link
Contributor

I've created a library to do just that.

@emoon
Copy link
Owner

emoon commented Feb 3, 2018

Yeah including such example would be easy. @tversteeg library seems handy as well but it might be a good idea to just include a very basic one that opens an image and displays it.

@tversteeg
Copy link
Contributor

tversteeg commented Feb 3, 2018

Here is a trait for drawing a RgbImage from the image library (got this from my library):

use image::*;

pub trait DrawExt {
    fn draw_to_buffer(&self, dst: &mut [u32], dst_width: usize, offset: (i32, i32));
}

impl DrawExt for RgbImage {
    fn draw_to_buffer(&self, dst: &mut [u32], dst_width: usize, offset: (i32, i32)) {
        let dst_size = (dst_width as i32, (dst.len() / dst_width) as i32);

        let (width, height) = self.dimensions();

        // Make sure only the pixels get rendered that are inside the dst
        let min_x = cmp::max(-offset.0, 0);
        let min_y = cmp::max(-offset.1, 0);

        let max_x = cmp::min(dst_size.0 - offset.0, width as i32);
        let max_y = cmp::min(dst_size.1 - offset.1, height as i32);

        for y in min_y..max_y {
            for x in min_x..max_x {
                let pixel = self.get_pixel(x as u32, y as u32).data;

                // Convert pixel to Color
                let raw = 0xFF000000 | ((pixel[0] as u32) << 16) | ((pixel[1] as u32) << 8) | (pixel[2] as u32);

                // Apply the offsets
                let dst_x = (x + offset.0) as usize;
                let dst_y = (y + offset.1) as usize;

                // Calculate the index
                let index = dst_x + dst_y * dst_size.0 as usize;
                dst[index] = raw.u32();
            }
        }
    }
}

const WIDTH: usize = 250;
const HEIGHT: usize = 250;

fn main() {
    let mut buffer: Vec<u32> = vec![0x00FFFFFF; WIDTH * HEIGHT];

    let img = image::open("img.png").unwrap();
    let rgb = img.as_rgb8().unwrap();

    rgb.draw_to_buffer(&mut buffer, WIDTH, (0, 0));
}

@emoon
Copy link
Owner

emoon commented Feb 3, 2018

Cool. Thanks!

@aeosynth
Copy link
Author

thanks, this is what I came up with combining @tversteeg's example and the minifb example:

extern crate image;
extern crate minifb;

use std::cmp;
use image::*;
use minifb::{Key, WindowOptions, Window};

pub trait DrawExt {
    fn draw_to_buffer(&self, dst: &mut [u32], dst_width: usize, offset: (i32, i32));
}

impl DrawExt for RgbImage {
    fn draw_to_buffer(&self, dst: &mut [u32], dst_width: usize, offset: (i32, i32)) {
        let dst_size = (dst_width as i32, (dst.len() / dst_width) as i32);

        let (width, height) = self.dimensions();

        // Make sure only the pixels get rendered that are inside the dst
        let min_x = cmp::max(-offset.0, 0);
        let min_y = cmp::max(-offset.1, 0);

        let max_x = cmp::min(dst_size.0 - offset.0, width as i32);
        let max_y = cmp::min(dst_size.1 - offset.1, height as i32);

        for y in min_y..max_y {
            for x in min_x..max_x {
                let pixel = self.get_pixel(x as u32, y as u32).data;

                // Convert pixel to Color
                let raw = 0xFF000000 | ((pixel[0] as u32) << 16) | ((pixel[1] as u32) << 8) | (pixel[2] as u32);

                // Apply the offsets
                let dst_x = (x + offset.0) as usize;
                let dst_y = (y + offset.1) as usize;

                // Calculate the index
                let index = dst_x + dst_y * dst_size.0 as usize;
                dst[index] = raw;
            }
        }
    }
}

const WIDTH: usize = 1024;
const HEIGHT: usize = 768;

fn main() {
    let mut buffer: Vec<u32> = vec![0x00FFFFFF; WIDTH * HEIGHT];

    let img = image::open("image.jpg").unwrap();
    let rgb = img.as_rgb8().unwrap();

    rgb.draw_to_buffer(&mut buffer, WIDTH, (0, 0));

    let mut window = Window::new("Test - ESC to exit",
                                 WIDTH,
                                 HEIGHT,
                                 WindowOptions::default()).unwrap_or_else(|e| {
        panic!("{}", e);
    });

    while window.is_open() && !window.is_key_down(Key::Escape) {
        // We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way
        window.update_with_buffer(&buffer).unwrap();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants