From 017762c462dc8771449aa765cf67efcfde0e4c3b Mon Sep 17 00:00:00 2001 From: Neil Gershenfeld <gersh@cba.mit.edu> Date: Mon, 27 Sep 2021 08:56:42 -0400 Subject: [PATCH] start line scanner --- modules/input/video | 51 ++++++++++- modules/processes/scan/line | 164 ++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 modules/processes/scan/line diff --git a/modules/input/video b/modules/input/video index 1faea25..14fe38c 100644 --- a/modules/input/video +++ b/modules/input/video @@ -28,7 +28,7 @@ var init = function() { mod.width.value = 640 mod.height.value = 480 mod.flip.checked = false - start_video() + list_video() } // // inputs @@ -67,6 +67,25 @@ var interface = function(div){ var canvas = document.createElement('canvas') mod.img = canvas // + // camera select + // + var select = document.createElement('select') + div.appendChild(select) + mod.select = select + div.appendChild(document.createElement('br')) + // + // start button + // + var btn = document.createElement('button') + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.appendChild(document.createTextNode('start')) + btn.addEventListener('click',function() { + start_video() + }) + div.appendChild(btn) + div.appendChild(document.createTextNode(' ')) + // // capture button // var btn = document.createElement('button') @@ -149,6 +168,24 @@ var interface = function(div){ // // local functions // +// add cameras to list +// +function list_video() { + navigator.mediaDevices.enumerateDevices() + .then(function(devices) { + devices.forEach(function(device) { + if (device.kind == 'videoinput') { + var el = document.createElement('option') + el.textContent = device.label + el.value = device.deviceId + mod.select.appendChild(el) + } + }) + }) + } +// +// start video +// function start_video() { var w = parseInt(mod.width.value) var h = parseInt(mod.height.value) @@ -157,19 +194,26 @@ function start_video() { ctx.canvas.height = h var constraints = { audio:false, - video:{width:w,height:h} + video:{ + width:w,height:h, + deviceId:{exact:mod.select.options[mod.select.selectedIndex].value} + } } navigator.mediaDevices.getUserMedia(constraints) .then(function(stream) { mod.video.srcObject = stream mod.video.onloadedmetadata = function(e) { mod.video.play() + capture_video() } }) .catch(function(err) { console.log(err.name+': '+err.message) }) } +// +// update video +// function update_video() { var w = parseInt(mod.width.value) var h = parseInt(mod.height.value) @@ -179,6 +223,9 @@ function update_video() { ctx.canvas.width = w ctx.canvas.height = h } +// +// capture video +// function capture_video() { var w = parseInt(mod.width.value) var h = parseInt(mod.height.value) diff --git a/modules/processes/scan/line b/modules/processes/scan/line new file mode 100644 index 0000000..54f823b --- /dev/null +++ b/modules/processes/scan/line @@ -0,0 +1,164 @@ +// +// line scan +// +// (c) MIT CBA Neil Gershenfeld 9/26/21 +// +// This work may be reproduced, modified, distributed, performed, and +// displayed for any purpose, but must acknowledge the fab modules +// project. Copyright is retained and must be preserved. The work is +// provided as is; no warranty is provided, and users accept all +// liability. +// +// closure +// +(function(){ +// +// module globals +// +var mod = {} +// +// name +// +var name = 'line scan' +// +// initialization +// +var init = function() { + mod.width.value = 10 + // + // open scan window + // + var win = window.open('') + win.document.title = "scan window" + win.document.body.appendChild(document.createElement('br')) + var canvas = document.createElement('canvas') + win.document.body.appendChild(canvas) + mod.scan = canvas + mod.win = win + } +// +// inputs +// +var inputs = { + image:{type:'RGBA', + event:function(evt) { + scanloop(evt.detail) + } + } + } +// +// outputs +// +var outputs = { + trigger:{type:'event', + event:function(){ + mods.output(mod,'trigger',null) + } + } + } +// +// interface +// +var interface = function(div){ + mod.div = div + // + // on-screen drawing canvas + // + var canvas = document.createElement('canvas') + canvas.width = mods.ui.canvas + canvas.height = mods.ui.canvas + canvas.style.backgroundColor = 'rgb(255,255,255)' + div.appendChild(canvas) + mod.img = canvas + div.appendChild(document.createElement('br')) + // + // line width + // + div.appendChild(document.createTextNode('scan line width (pixels): ')) + var input = document.createElement('input') + input.type = 'text' + input.size = 6 + input.addEventListener('change',function(){ + alert('width') + }) + div.appendChild(input) + mod.width = input + // + // start scan button + // + div.appendChild(document.createElement('br')) + div.appendChild(document.createTextNode(' ')) + var btn = document.createElement('button') + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.appendChild(document.createTextNode('start scan')) + btn.addEventListener('click',function(){ + linescan() + }) + div.appendChild(btn) + } +// +// local functions +// +// line scan +// +function linescan() { + mod.l = parseFloat(mod.width.value) + mod.w = mod.win.innerWidth + mod.h = mod.win.innerHeight + mod.scan.width = mod.w + mod.scan.height = mod.h + mod.y = 0 + mod.state = 'start' + scanloop(null) + } +// +// scan loop +// +function scanloop(input) { + if (mod.state == 'start') { + // + // take background + // + var ctx = mod.scan.getContext("2d") + ctx.fillStyle = "black" + ctx.fillRect(0,0,mod.w,mod.h) + mod.state = 'background' + outputs.trigger.event() + } + else if (mod.state == 'background') { + // + // save background, start scan + // + mod.state = 'scan' + outputs.trigger.event() + } + else if (mod.state == 'scan') { + // + // scan + // + mod.y += mod.l + var ctx = mod.scan.getContext("2d") + ctx.lineWidth = mod.l + ctx.fillStyle = "black" + ctx.fillRect(0,0,mod.w,mod.h) + ctx.strokeStyle = "white" + ctx.beginPath() + ctx.moveTo(0,mod.y) + ctx.lineTo(mod.w,mod.y) + ctx.stroke() + if (mod.y < mod.h) + outputs.trigger.event() + } + } +// +// return values +// +return ({ + name:name, + init:init, + inputs:inputs, + outputs:outputs, + interface:interface + }) +}()) -- GitLab