Skip to content
Snippets Groups Projects
Commit 00a1b6fc authored by Neil Gershenfeld's avatar Neil Gershenfeld
Browse files

wip

parent 93fbac4a
Branches
No related tags found
No related merge requests found
...@@ -32,10 +32,7 @@ var init = function() { ...@@ -32,10 +32,7 @@ var init = function() {
mod.latency.value = 15 mod.latency.value = 15
mod.delay.value = 1 mod.delay.value = 1
mod.dpi = 100 mod.dpi = 100
// mod.win = null
// open window for last image
//
open_window()
// //
// trigger image after latency (for start-up) // trigger image after latency (for start-up)
// //
...@@ -98,6 +95,33 @@ var interface = function(div){ ...@@ -98,6 +95,33 @@ var interface = function(div){
// //
var canvas = document.createElement('canvas') var canvas = document.createElement('canvas')
mod.lastimg = canvas mod.lastimg = canvas
div.appendChild(document.createElement('br'))
//
// view button
//
var btn = document.createElement('button')
btn.style.padding = mods.ui.padding
btn.style.margin = 1
btn.appendChild(document.createTextNode('view last image'))
btn.addEventListener('click',function(){
mod.win = window.open('')
mod.win.document.title = 'motion detect last image'
mod.win.document.body.style.overflow = 'hidden'
mod.win.document.body.style.border = 0
mod.win.document.body.style.padding = 0
mod.win.document.body.style.margin = 0
mod.win.addEventListener('unload',function() {
mod.win = null
})
var canvas = document.createElement('canvas')
canvas.width = mod.img.width
canvas.height = mod.img.height
canvas.setAttribute('id',mod.div.id+'canvas')
mod.win.document.body.appendChild(canvas)
var ctx = canvas.getContext("2d")
ctx.drawImage(mod.img,0,0)
})
div.appendChild(btn)
// //
// info div // info div
// //
...@@ -220,12 +244,14 @@ function compare_images() { ...@@ -220,12 +244,14 @@ function compare_images() {
// //
// update view window // update view window
// //
if (mod.win != null) {
var canvas = mod.win.document.getElementById(mod.div.id+'canvas') var canvas = mod.win.document.getElementById(mod.div.id+'canvas')
canvas.width = mod.img.width canvas.width = mod.img.width
canvas.height = mod.img.height canvas.height = mod.img.height
var ctx = canvas.getContext("2d") var ctx = canvas.getContext("2d")
ctx.clearRect(0,0,mod.img.width,mod.img.height) ctx.clearRect(0,0,mod.img.width,mod.img.height)
ctx.drawImage(mod.img,0,0) ctx.drawImage(mod.img,0,0)
}
// //
// terminate worker // terminate worker
// //
......
{"modules":{"0.10092185293872713":{"definition":"//\n// convert rgba jpg\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2017\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'convert RGBA to JPG'\n//\n// initialization\n//\nvar init = function() {\n mod.name.value = \"file.jpg\"\n mod.compress.value = .75\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = evt.detail.width\n ctx.canvas.height = evt.detail.height \n ctx.putImageData(evt.detail,0,0)\n mod.pxtext.nodeValue = evt.detail.width+' x '+evt.detail.height+' px'\n convert_image()\n }},\n imageInfo:{type:'object',\n event:function(evt){\n mod.name.value = evt.detail.name+'.jpg'\n }}\n }\n//\n// outputs\n//\nvar outputs = {\n }\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n var win = window.open('')\n var btn = document.createElement('button')\n btn.appendChild(document.createTextNode('close'))\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.addEventListener('click',function(){\n win.close()\n })\n win.document.body.appendChild(btn)\n win.document.body.appendChild(document.createElement('br'))\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // info div\n //\n var info = document.createElement('div')\n info.appendChild(document.createTextNode('file name: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.name = input\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('compression: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.compress = input\n info.appendChild(document.createTextNode(' (0-1)'))\n info.appendChild(document.createElement('br'))\n var text = document.createTextNode('px: ')\n info.appendChild(text)\n mod.pxtext = text\n div.appendChild(info)\n }\n//\n// local functions\n//\nfunction convert_image() {\n //\n // preview\n //\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n //\n // convert and save\n //\n mod.img.toBlob(function(blob){\n var url = URL.createObjectURL(blob)\n var link = document.createElement('a')\n link.download = mod.name.value\n link.href = url\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n URL.revokeObjectURL(url)\n },'image/jpeg',parseFloat(mod.compress.value))\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"142","left":"1098","inputs":{},"outputs":{}},"0.4997564076516918":{"definition":"//\n// video\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'video'\n//\n// initialization\n//\nvar init = function() {\n mod.width.value = 1280 \n mod.height.value = 720\n mod.flip.checked = false\n start_video()\n }\n//\n// inputs\n//\nvar inputs = {\n capture:{type:'event',\n event:function(evt){\n capture_video()}}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // capture button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('capture'))\n btn.addEventListener('click',function() {\n capture_video()\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n var win = window.open('')\n var btn = document.createElement('button')\n btn.appendChild(document.createTextNode('close'))\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.addEventListener('click',function(){\n win.close()\n })\n win.document.body.appendChild(btn)\n win.document.body.appendChild(document.createElement('br'))\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n div.appendChild(document.createElement('br'))\n //\n // width\n //\n div.appendChild(document.createTextNode('width: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function() {\n update_video()\n })\n div.appendChild(input)\n mod.width = input\n div.appendChild(document.createElement('br'))\n //\n // height\n //\n div.appendChild(document.createTextNode(' height: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function() {\n update_video()\n })\n div.appendChild(input)\n mod.height = input\n div.appendChild(document.createElement('br'))\n //\n // flip\n //\n div.appendChild(document.createTextNode('flip image: '))\n var input = document.createElement('input')\n input.type = 'checkbox'\n div.appendChild(input)\n mod.flip = input\n div.appendChild(document.createElement('br'))\n //\n // video element\n //\n var video = document.createElement('video')\n mod.video = video\n }\n//\n// local functions\n//\nfunction start_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = w\n ctx.canvas.height = h\n var constraints = {\n audio:false,\n video:{width:w,height:h}\n }\n navigator.mediaDevices.getUserMedia(constraints)\n .then(function(stream) {\n mod.video.srcObject = stream\n mod.video.onloadedmetadata = function(e) {\n mod.video.play()\n }\n })\n .catch(function(err) {\n console.log(err.name + \": \"+err.message)\n })\n }\nfunction update_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n mod.video.setAttribute('width',w)\n mod.video.setAttribute('height',h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = w\n ctx.canvas.height = h\n }\nfunction capture_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.drawImage(mod.video,0,0,w,h)\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n var h = mod.img.height\n var w = mod.img.width\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var imgdata = new ImageData(buf,w,h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(imgdata,0,0)\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n outputs.image.event()\n webworker.terminate()\n })\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:mod.img.height,width:mod.img.width,\n checked:mod.flip.checked,\n buffer:img.data.buffer},[img.data.buffer])\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var checked = evt.data.checked\n var buf = new Uint8ClampedArray(evt.data.buffer)\n if (checked == true) {\n var newbuf = new Uint8ClampedArray(buf.length)\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n newbuf[(h-1-row)*w*4+col*4+0] = \n buf[row*w*4+(w-1-col)*4+0] \n newbuf[(h-1-row)*w*4+col*4+1] = \n buf[row*w*4+(w-1-col)*4+1]\n newbuf[(h-1-row)*w*4+col*4+2] = \n buf[row*w*4+(w-1-col)*4+2]\n newbuf[(h-1-row)*w*4+col*4+3] = \n buf[row*w*4+(w-1-col)*4+3]\n }\n }\n self.postMessage({buffer:newbuf.buffer},[newbuf.buffer])\n }\n else\n self.postMessage({buffer:buf.buffer},[buf.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"302","left":"738","inputs":{},"outputs":{}},"0.7338376248661294":{"definition":"//\n// motion detect\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2017\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'motion detect'\n//\n// initialization\n//\nvar init = function() {\n //\n // UI settings\n //\n mod.threshold.value = 0.025\n mod.latency.value = 15\n mod.delay.value = 1\n mod.dpi = 100\n //\n // open window for last image\n //\n open_window()\n //\n // trigger image after latency (for start-up)\n //\n setTimeout(outputs.trigger.event,\n parseFloat(mod.latency.value)*1000)\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n var ctx = mod.img.getContext(\"2d\")\n var lastctx = mod.lastimg.getContext(\"2d\")\n lastctx.canvas.width = ctx.canvas.width\n lastctx.canvas.height = ctx.canvas.height\n lastctx.drawImage(mod.img,0,0)\n ctx.canvas.width = evt.detail.width\n ctx.canvas.height = evt.detail.height \n ctx.putImageData(evt.detail,0,0)\n compare_images()\n }}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)}},\n imageInfo:{type:'object',\n event:function(obj){\n mods.output(mod,'imageInfo',obj)}},\n trigger:{type:'event',\n event:function(){\n mods.output(mod,'trigger',null)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // off-screen last image canvas\n //\n var canvas = document.createElement('canvas')\n mod.lastimg = canvas\n //\n // info div\n //\n var info = document.createElement('div')\n var text = document.createTextNode('relative change: ')\n info.appendChild(text)\n mod.changetext = text\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('threshold: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.threshold = input\n info.appendChild(document.createTextNode(' (0-1)'))\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('latency: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.latency = input\n info.appendChild(document.createTextNode(' (s)'))\n div.appendChild(info)\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('delay: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.delay = input\n info.appendChild(document.createTextNode(' (s)'))\n div.appendChild(info)\n }\n//\n// local functions\n//\nfunction open_window() {\n mod.win = window.open('')\n mod.win.document.title = 'motion detect last image'\n mod.win.document.body.style.overflow = 'hidden'\n mod.win.document.body.style.border = 0\n mod.win.document.body.style.padding = 0\n mod.win.document.body.style.margin = 0\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n canvas.setAttribute('id',mod.div.id+'canvas')\n mod.win.document.body.appendChild(canvas)\n }\nfunction compare_images() {\n //\n // create worker\n //\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n //\n // worker handler\n //\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n mod.changetext.nodeValue = 'relative change: '+evt.data.change.toFixed(3)\n mod.change = evt.data.change\n //\n // check if change > threshold\n //\n if (mod.change > parseFloat(mod.threshold.value)) {\n //\n // yes, output image\n //\n var obj = {}\n var date = new Date()\n var year = date.getFullYear()\n var month = ('0'+(1+parseInt(date.getMonth()))).slice(-2)\n var day = ('0'+date.getDate()).slice(-2)\n var hour = ('0'+date.getHours()).slice(-2)\n var minute = ('0'+date.getMinutes()).slice(-2)\n var second = ('0'+date.getSeconds()).slice(-2)\n var name = year+'-'+month+'-'+day+'-'+hour+'-'+minute+'-'+second\n obj.name = name\n obj.dpi = mod.dpi\n obj.width = mod.img.width\n obj.height = mod.img.height\n outputs.imageInfo.event(obj)\n outputs.image.event()\n //\n // trigger next image after latency\n //\n setTimeout(outputs.trigger.event,\n parseFloat(mod.latency.value)*1000)\n }\n else {\n //\n // no, trigger next image after delay\n //\n setTimeout(outputs.trigger.event,\n parseFloat(mod.delay.value)*1000)\n }\n //\n // update canvas\n //\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n //\n // update view window\n //\n var canvas = mod.win.document.getElementById(mod.div.id+'canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n var ctx = canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.img.width,mod.img.height)\n ctx.drawImage(mod.img,0,0)\n //\n // terminate worker\n //\n webworker.terminate()\n })\n //\n // call worker\n //\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n var ctx = mod.lastimg.getContext(\"2d\")\n var lastimg = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n var t = parseFloat(mod.threshold.value)\n webworker.postMessage({\n height:mod.img.height,width:mod.img.width,threshold:t,\n buffer:img.data.buffer,lastbuffer:lastimg.data.buffer})\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var t = evt.data.threshold\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var lastbuf = new Uint8ClampedArray(evt.data.lastbuffer)\n var change = 0\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n r = buf[(h-1-row)*w*4+col*4+0] \n g = buf[(h-1-row)*w*4+col*4+1] \n b = buf[(h-1-row)*w*4+col*4+2] \n rl = lastbuf[(h-1-row)*w*4+col*4+0] \n gl = lastbuf[(h-1-row)*w*4+col*4+1] \n bl = lastbuf[(h-1-row)*w*4+col*4+2] \n change += (Math.abs(r-rl)/255 \n +Math.abs(g-gl)/255\n +Math.abs(b-bl)/255)/3\n }\n }\n change = change/(w*h)\n self.postMessage({change:change})\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"142","left":"219","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.7338376248661294\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10092185293872713\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7338376248661294\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10092185293872713\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7338376248661294\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"trigger\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.4997564076516918\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"capture\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.4997564076516918\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.7338376248661294\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}"]} {"modules":{"0.10092185293872713":{"definition":"//\n// convert rgba jpg\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2017\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'convert RGBA to JPG'\n//\n// initialization\n//\nvar init = function() {\n mod.name.value = \"file.jpg\"\n mod.compress.value = .75\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = evt.detail.width\n ctx.canvas.height = evt.detail.height \n ctx.putImageData(evt.detail,0,0)\n mod.pxtext.nodeValue = evt.detail.width+' x '+evt.detail.height+' px'\n convert_image()\n }},\n imageInfo:{type:'object',\n event:function(evt){\n mod.name.value = evt.detail.name+'.jpg'\n }}\n }\n//\n// outputs\n//\nvar outputs = {\n }\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n var win = window.open('')\n var btn = document.createElement('button')\n btn.appendChild(document.createTextNode('close'))\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.addEventListener('click',function(){\n win.close()\n })\n win.document.body.appendChild(btn)\n win.document.body.appendChild(document.createElement('br'))\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // info div\n //\n var info = document.createElement('div')\n info.appendChild(document.createTextNode('file name: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.name = input\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('compression: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.compress = input\n info.appendChild(document.createTextNode(' (0-1)'))\n info.appendChild(document.createElement('br'))\n var text = document.createTextNode('px: ')\n info.appendChild(text)\n mod.pxtext = text\n div.appendChild(info)\n }\n//\n// local functions\n//\nfunction convert_image() {\n //\n // preview\n //\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n //\n // convert and save\n //\n mod.img.toBlob(function(blob){\n var url = URL.createObjectURL(blob)\n var link = document.createElement('a')\n link.download = mod.name.value\n link.href = url\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n URL.revokeObjectURL(url)\n },'image/jpeg',parseFloat(mod.compress.value))\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"142","left":"1098","inputs":{},"outputs":{}},"0.4997564076516918":{"definition":"//\n// video\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'video'\n//\n// initialization\n//\nvar init = function() {\n mod.width.value = 1280 \n mod.height.value = 720\n mod.flip.checked = false\n start_video()\n }\n//\n// inputs\n//\nvar inputs = {\n capture:{type:'event',\n event:function(evt){\n capture_video()}}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // capture button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('capture'))\n btn.addEventListener('click',function() {\n capture_video()\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n var win = window.open('')\n var btn = document.createElement('button')\n btn.appendChild(document.createTextNode('close'))\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.addEventListener('click',function(){\n win.close()\n })\n win.document.body.appendChild(btn)\n win.document.body.appendChild(document.createElement('br'))\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n div.appendChild(document.createElement('br'))\n //\n // width\n //\n div.appendChild(document.createTextNode('width: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function() {\n update_video()\n })\n div.appendChild(input)\n mod.width = input\n div.appendChild(document.createElement('br'))\n //\n // height\n //\n div.appendChild(document.createTextNode(' height: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function() {\n update_video()\n })\n div.appendChild(input)\n mod.height = input\n div.appendChild(document.createElement('br'))\n //\n // flip\n //\n div.appendChild(document.createTextNode('flip image: '))\n var input = document.createElement('input')\n input.type = 'checkbox'\n div.appendChild(input)\n mod.flip = input\n div.appendChild(document.createElement('br'))\n //\n // video element\n //\n var video = document.createElement('video')\n mod.video = video\n }\n//\n// local functions\n//\nfunction start_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = w\n ctx.canvas.height = h\n var constraints = {\n audio:false,\n video:{width:w,height:h}\n }\n navigator.mediaDevices.getUserMedia(constraints)\n .then(function(stream) {\n mod.video.srcObject = stream\n mod.video.onloadedmetadata = function(e) {\n mod.video.play()\n }\n })\n .catch(function(err) {\n console.log(err.name + \": \"+err.message)\n })\n }\nfunction update_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n mod.video.setAttribute('width',w)\n mod.video.setAttribute('height',h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = w\n ctx.canvas.height = h\n }\nfunction capture_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.drawImage(mod.video,0,0,w,h)\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n var h = mod.img.height\n var w = mod.img.width\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var imgdata = new ImageData(buf,w,h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(imgdata,0,0)\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n outputs.image.event()\n webworker.terminate()\n })\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:mod.img.height,width:mod.img.width,\n checked:mod.flip.checked,\n buffer:img.data.buffer},[img.data.buffer])\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var checked = evt.data.checked\n var buf = new Uint8ClampedArray(evt.data.buffer)\n if (checked == true) {\n var newbuf = new Uint8ClampedArray(buf.length)\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n newbuf[(h-1-row)*w*4+col*4+0] = \n buf[row*w*4+(w-1-col)*4+0] \n newbuf[(h-1-row)*w*4+col*4+1] = \n buf[row*w*4+(w-1-col)*4+1]\n newbuf[(h-1-row)*w*4+col*4+2] = \n buf[row*w*4+(w-1-col)*4+2]\n newbuf[(h-1-row)*w*4+col*4+3] = \n buf[row*w*4+(w-1-col)*4+3]\n }\n }\n self.postMessage({buffer:newbuf.buffer},[newbuf.buffer])\n }\n else\n self.postMessage({buffer:buf.buffer},[buf.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"302","left":"738","inputs":{},"outputs":{}},"0.30101921769726425":{"definition":"//\n// motion detect\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2017\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'motion detect'\n//\n// initialization\n//\nvar init = function() {\n //\n // UI settings\n //\n mod.threshold.value = 0.025\n mod.latency.value = 15\n mod.delay.value = 1\n mod.dpi = 100\n mod.win = null\n //\n // trigger image after latency (for start-up)\n //\n setTimeout(outputs.trigger.event,\n parseFloat(mod.latency.value)*1000)\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n var ctx = mod.img.getContext(\"2d\")\n var lastctx = mod.lastimg.getContext(\"2d\")\n lastctx.canvas.width = ctx.canvas.width\n lastctx.canvas.height = ctx.canvas.height\n lastctx.drawImage(mod.img,0,0)\n ctx.canvas.width = evt.detail.width\n ctx.canvas.height = evt.detail.height \n ctx.putImageData(evt.detail,0,0)\n compare_images()\n }}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)}},\n imageInfo:{type:'object',\n event:function(obj){\n mods.output(mod,'imageInfo',obj)}},\n trigger:{type:'event',\n event:function(){\n mods.output(mod,'trigger',null)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // off-screen last image canvas\n //\n var canvas = document.createElement('canvas')\n mod.lastimg = canvas\n div.appendChild(document.createElement('br'))\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view last image'))\n btn.addEventListener('click',function(){\n mod.win = window.open('')\n mod.win.document.title = 'motion detect last image'\n mod.win.document.body.style.overflow = 'hidden'\n mod.win.document.body.style.border = 0\n mod.win.document.body.style.padding = 0\n mod.win.document.body.style.margin = 0\n mod.win.addEventListener('unload',function() {\n mod.win = null\n })\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n canvas.setAttribute('id',mod.div.id+'canvas')\n mod.win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n //\n // info div\n //\n var info = document.createElement('div')\n var text = document.createTextNode('relative change: ')\n info.appendChild(text)\n mod.changetext = text\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('threshold: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.threshold = input\n info.appendChild(document.createTextNode(' (0-1)'))\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('latency: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.latency = input\n info.appendChild(document.createTextNode(' (s)'))\n div.appendChild(info)\n info.appendChild(document.createElement('br'))\n info.appendChild(document.createTextNode('delay: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.delay = input\n info.appendChild(document.createTextNode(' (s)'))\n div.appendChild(info)\n }\n//\n// local functions\n//\nfunction open_window() {\n mod.win = window.open('')\n mod.win.document.title = 'motion detect last image'\n mod.win.document.body.style.overflow = 'hidden'\n mod.win.document.body.style.border = 0\n mod.win.document.body.style.padding = 0\n mod.win.document.body.style.margin = 0\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n canvas.setAttribute('id',mod.div.id+'canvas')\n mod.win.document.body.appendChild(canvas)\n }\nfunction compare_images() {\n //\n // create worker\n //\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n //\n // worker handler\n //\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n mod.changetext.nodeValue = 'relative change: '+evt.data.change.toFixed(3)\n mod.change = evt.data.change\n //\n // check if change > threshold\n //\n if (mod.change > parseFloat(mod.threshold.value)) {\n //\n // yes, output image\n //\n var obj = {}\n var date = new Date()\n var year = date.getFullYear()\n var month = ('0'+(1+parseInt(date.getMonth()))).slice(-2)\n var day = ('0'+date.getDate()).slice(-2)\n var hour = ('0'+date.getHours()).slice(-2)\n var minute = ('0'+date.getMinutes()).slice(-2)\n var second = ('0'+date.getSeconds()).slice(-2)\n var name = year+'-'+month+'-'+day+'-'+hour+'-'+minute+'-'+second\n obj.name = name\n obj.dpi = mod.dpi\n obj.width = mod.img.width\n obj.height = mod.img.height\n outputs.imageInfo.event(obj)\n outputs.image.event()\n //\n // trigger next image after latency\n //\n setTimeout(outputs.trigger.event,\n parseFloat(mod.latency.value)*1000)\n }\n else {\n //\n // no, trigger next image after delay\n //\n setTimeout(outputs.trigger.event,\n parseFloat(mod.delay.value)*1000)\n }\n //\n // update canvas\n //\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n //\n // update view window\n //\n if (mod.win != null) {\n var canvas = mod.win.document.getElementById(mod.div.id+'canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n var ctx = canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.img.width,mod.img.height)\n ctx.drawImage(mod.img,0,0)\n }\n //\n // terminate worker\n //\n webworker.terminate()\n })\n //\n // call worker\n //\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n var ctx = mod.lastimg.getContext(\"2d\")\n var lastimg = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n var t = parseFloat(mod.threshold.value)\n webworker.postMessage({\n height:mod.img.height,width:mod.img.width,threshold:t,\n buffer:img.data.buffer,lastbuffer:lastimg.data.buffer})\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var t = evt.data.threshold\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var lastbuf = new Uint8ClampedArray(evt.data.lastbuffer)\n var change = 0\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n r = buf[(h-1-row)*w*4+col*4+0] \n g = buf[(h-1-row)*w*4+col*4+1] \n b = buf[(h-1-row)*w*4+col*4+2] \n rl = lastbuf[(h-1-row)*w*4+col*4+0] \n gl = lastbuf[(h-1-row)*w*4+col*4+1] \n bl = lastbuf[(h-1-row)*w*4+col*4+2] \n change += (Math.abs(r-rl)/255 \n +Math.abs(g-gl)/255\n +Math.abs(b-bl)/255)/3\n }\n }\n change = change/(w*h)\n self.postMessage({change:change})\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"142","left":"241","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.30101921769726425\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10092185293872713\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.30101921769726425\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10092185293872713\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.30101921769726425\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"trigger\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.4997564076516918\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"capture\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.4997564076516918\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.30101921769726425\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}"]}
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment