Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
mods
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
mods
Commits
9105e371
Commit
9105e371
authored
7 years ago
by
Neil Gershenfeld
Browse files
Options
Downloads
Patches
Plain Diff
wip
parent
a038615a
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
programs/image/motion detect
+1
-1
1 addition, 1 deletion
programs/image/motion detect
with
1 addition
and
1 deletion
programs/image/motion detect
+
1
−
1
View file @
9105e371
{"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
{"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.5045640640829611":{"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 = '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":"140","left":"232","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.5045640640829611\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10092185293872713\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5045640640829611\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10092185293872713\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5045640640829611\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"trigger\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.4997564076516918\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"capture\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.4997564076516918\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5045640640829611\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}"]}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment