Being able to draw webcam to canvas, yay
This commit is contained in:
commit
190f71bf06
4 changed files with 2788 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
2634
Cargo.lock
generated
Normal file
2634
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "testproject"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Ruben van de Ven <git@rubenvandeven.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nannou = "0.14"
|
||||||
|
# clang-sys = "0.29.3"
|
||||||
|
v4l = {version = "0.5.1", features = ["libv4l"]}
|
||||||
|
|
||||||
|
# image2 = "0.11.3" # seems deprecated and advices imaged
|
||||||
|
# rscam = "0.5.5"
|
138
src/main.rs
Normal file
138
src/main.rs
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
use nannou::prelude::*;
|
||||||
|
use v4l::{Buffer, CaptureDevice, MappedBufferStream};
|
||||||
|
use nannou::image;
|
||||||
|
|
||||||
|
static mut CAMERA: Option<CaptureDevice> = None;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
unsafe{
|
||||||
|
CAMERA = Some(CaptureDevice::new(2)
|
||||||
|
.expect("Failed to open device")
|
||||||
|
.format(640, 480, b"RGB3")
|
||||||
|
.expect("Failed to set format")
|
||||||
|
.fps(60)
|
||||||
|
.expect("Failed to set frame interval"));
|
||||||
|
}
|
||||||
|
|
||||||
|
nannou::app(model)
|
||||||
|
.event(event)
|
||||||
|
.update(update)
|
||||||
|
.view(view)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Model<'a> {
|
||||||
|
stream: MappedBufferStream<'a>,
|
||||||
|
_window: window::Id,
|
||||||
|
image: Option<nannou::image::DynamicImage>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn model<'a>(app: &App) -> Model<'a> {
|
||||||
|
// Create a new capture device with a few extra parameters
|
||||||
|
unsafe{
|
||||||
|
let stream = MappedBufferStream::with_buffers(CAMERA.as_mut().unwrap(), 4)
|
||||||
|
.expect("Failed to create buffer stream");
|
||||||
|
|
||||||
|
let _window = app.new_window()
|
||||||
|
.size(720, 720)
|
||||||
|
// .event(window_event)
|
||||||
|
// .raw_event(raw_window_event)
|
||||||
|
// .key_pressed(key_pressed)
|
||||||
|
// .key_released(key_released)
|
||||||
|
// .mouse_moved(mouse_moved)
|
||||||
|
// .mouse_pressed(mouse_pressed)
|
||||||
|
// .mouse_released(mouse_released)
|
||||||
|
// .mouse_wheel(mouse_wheel)
|
||||||
|
// .mouse_entered(mouse_entered)
|
||||||
|
// .mouse_exited(mouse_exited)
|
||||||
|
// .touch(touch)
|
||||||
|
// .touchpad_pressure(touchpad_pressure)
|
||||||
|
// .moved(window_moved)
|
||||||
|
// .resized(window_resized)
|
||||||
|
// .hovered_file(hovered_file)
|
||||||
|
// .hovered_file_cancelled(hovered_file_cancelled)
|
||||||
|
// .dropped_file(dropped_file)
|
||||||
|
// .focused(window_focused)
|
||||||
|
// .unfocused(window_unfocused)
|
||||||
|
// .closed(window_closed)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Model {
|
||||||
|
stream: stream,
|
||||||
|
_window: _window,
|
||||||
|
image: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(_app: &App, _model: &mut Model, event: Event) {
|
||||||
|
match event {
|
||||||
|
Event::WindowEvent {
|
||||||
|
id: _window_id,
|
||||||
|
//raw: _,
|
||||||
|
simple: _simple,
|
||||||
|
} => {
|
||||||
|
match _simple {
|
||||||
|
None => {println!("Unkown window event")}
|
||||||
|
// Some(nannou::event::WindowEvent:Moved(_)) => {println!("moved! {:?}", _simple.unwrap())}
|
||||||
|
Some(_ev) => { println!("Any other window event! {:?}", _ev) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::DeviceEvent(_device_id, _event) => {}
|
||||||
|
Event::Update(_dt) => {}
|
||||||
|
Event::Suspended => {}
|
||||||
|
Event::Resumed => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(_app: &App, _model: &mut Model, _update: Update) {
|
||||||
|
|
||||||
|
let frame = _model.stream.next().unwrap();
|
||||||
|
// let vec: Vec<u8> = frame.data().to_vec();
|
||||||
|
let img_buffer = nannou::image::ImageBuffer::from_raw(640,480, frame.data().to_vec());
|
||||||
|
match img_buffer {
|
||||||
|
None => {
|
||||||
|
_model.image = None;
|
||||||
|
}
|
||||||
|
Some(ib) => {
|
||||||
|
// let
|
||||||
|
// ib.map( nannou::image::DynamicImage::ImageRgb8);
|
||||||
|
_model.image = Some(nannou::image::DynamicImage::ImageRgb8(ib));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("Fetch frame nr {:?} {:?} {:?}", frame.meta().seq, frame.meta().timestamp, frame.data())
|
||||||
|
// println!("Fetch frame nr {:?} {:?} {:?} {:?}", frame.meta().seq, frame.meta().timestamp, frame.meta().flags, frame.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn view(_app: &App, _model: &Model, frame: Frame){
|
||||||
|
let draw = _app.draw();
|
||||||
|
draw.background().color(PLUM);
|
||||||
|
let sine = (_app.time / 1.0).sin();
|
||||||
|
let slowersine = (_app.time / 3.0).sin();
|
||||||
|
let rotation = _app.time % (2. * PI);
|
||||||
|
let boundary = _app.window_rect();
|
||||||
|
let x = map_range(sine, -1.0, 1.0, boundary.left(), boundary.right());
|
||||||
|
let y = map_range(slowersine, -1.0, 1.0, boundary.bottom(), boundary.top());
|
||||||
|
|
||||||
|
// let texture = wgpu::Texture::load_from_
|
||||||
|
// let assets = _app.assets_path().unwrap();
|
||||||
|
// let img_path = assets.join("test1.png");
|
||||||
|
// let texture = wgpu::Texture::from_path(_app, img_path).unwrap();
|
||||||
|
|
||||||
|
// let image = nannou::image::DynamicImage::new_rgb8(640, 480);
|
||||||
|
match &_model.image {
|
||||||
|
Some(dynamic_image) => {
|
||||||
|
let texture = wgpu::Texture::from_image(_app, dynamic_image);
|
||||||
|
draw.texture(&texture);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.rect().color(STEELBLUE).rotate(rotation).x_y(x,y);
|
||||||
|
draw.to_frame(_app, &frame).unwrap();
|
||||||
|
}
|
Loading…
Reference in a new issue