基本情報

このページではIoTコンテンツ(Webカメラ)をベースにして、新しいコンテンツを「フォーク」できます。フォークしたコンテンツは、プロジェクトの一覧ページに新しい項目として表示されます。元の項目を上書きしたい場合は編集してください。

※写真URLは.jpg, .jpeg, .pngのいずれかで終わるもの、またはGyazoへアップロードされたページのURL(https://gyazo.com/hogehogeなど)に対応しています。

{ "dependencies": { "twitter": "latest" } }

※IoTコンテンツの説明、エントリポイントに関する情報 main: index.js およびf3jsモジュールへの依存情報 dependencies: { f3js: (略) } は、この欄の内容とマージされるため記入不要です。

カードのプレビュー
Webカメラ
'16/7/8 9:53
Intel EdisonにUSB接続したカメラで写真を撮影したり配信したりします。
OnCounter

プライベートコンテンツ

チェックを外すと、このコンテンツはすぐ一覧に公開され、誰でもアクセスできるようになります。 なるべくコンテンツを共有していただきたいので、チェックは初めから外れています。また、ログインしていない状態ではチェックをつけられません。 一度公開されたコンテンツは、プライベートにできません。(一度チェックを外すと、以降そのコンテンツを編集するときにはチェックをつけられなくなります。)

ソースコード

マイコン・小型コンピュータのプログラムのソースコードを記述してください。f3jsパッケージをrequireすることで筐体設計が可能です。詳しくはAPIドキュメントをご覧ください。

var dirPath = '/home/root/camera' , f3js = require('f3js') , Grove = require('jsupm_grove') , CircularLED = require('jsupm_my9221').GroveCircularLED , level = 0; //, Twitter = require('twitter'); // FIXME function execute(cmd, args, onEnd) { var spawn = require('child_process').spawn , child = spawn(cmd, args) , me = this; me.stdout = ''; me.stderr = ''; child.stdout.on('data', function (data) { me.stdout += data.toString(); }); child.stderr.on('data', function (data) { me.stderr += data.toString(); }); child.stdout.on('end', function () { if (onEnd) { onEnd(me); } }); } function takePicture(callback) { var filePath = dirPath + '/picture.jpg'; circularLED.setLevel(24); new execute( 'fswebcam' , ['--no-banner', '-r', '1920x1080', '-S', '30', filePath] , function (me) { circularLED.setLevel(level); callback(filePath); }); } var thickness = 2 // thickness [1, 5] , depth = 45 , button = new Grove.GroveButton(3) , circularLED = new CircularLED(5, 4) , oc = f3js.cc() // offset container , front = oc.cc() , rect = front.jrc(0, 0, 130, 77); oc.x = 5; oc.y = 5; oc.add(front); rect.jointWidth = 10; rect.jointHeight = thickness; front.add(circularLED, rect.width/2, rect.height/2 + 10); front.rc(rect.width/2 - 10, 10, 20, 10); var planes = rect.extrude(depth); planes[4].x = 0; planes[4].y = rect.height; oc.add(planes[4]); planes[0].x = 0; planes[0].y = rect.height * 2; oc.add(planes[0]); planes[2].x = 0; planes[2].y = rect.height * 2 + depth; oc.add(planes[2]); planes[1].x = 0; planes[1].y = rect.height * 2 + depth * 2; oc.add(planes[1]); planes[3].x = rect.height - thickness; planes[3].y = rect.height * 2 + depth * 2; oc.add(planes[3]); planes[0].c(rect.width / 2 - 15, 10, 4); planes[0].c(rect.width / 2 + 15, 10, 4); var cableHoleOffset = 2; planes[1].rc( 5, depth - 10 - thickness * 2 - cableHoleOffset, rect.height - 10, 10); var bc = planes[1].add(button, 20, 15); bc.rotation = 90; var isTakingPicture = false; function checkButtonPress() { if (button.value() <= 0 || isTakingPicture) return; console.log('take a picture via hardware request'); isTakingPicture = true; takePicture(function (filePath) { console.log('took a picture:', filePath); isTakingPicture = false; }); } var http = require('http') , url = require('url') , path = require('path') , fs = require('fs') , mimeTypes = { "html": "text/html" , "jpeg": "image/jpeg" , "jpg": "image/jpeg" , "png": "image/png" , "js": "text/javascript" , "css": "text/css"}; function handleRequest(req, res){ var uri = url.parse(req.url).pathname , filePath = path.join(dirPath, uri) , stats; if (uri.toLowerCase() === '/shoot') { if (isTakingPicture) { busy(); return; } console.log('take a picture via HTTP request'); takePicture(function (filePath) { console.log('took a picture:', filePath); res.writeHead(200, {'Content-Type': 'text/plain'}); res.write('200 OK: took a picture\n'); res.end(); isTakingPicture = false; }); return; } var setLevel = /\/set\/brightness\/([0-9]+)/.exec(); if (setLevel) { var l = parseInt(setLevel[1]); if (l >= 0 && l <= 24) { circularLED.setLevel(l); level = l; } console.log('set level:', level); res.writeHead(200, {'Content-Type': 'text/plain'}); res.write('200 OK: set level to ' + level + '\n'); res.end(); return; } try { stats = fs.lstatSync(filePath); // throws if path doesn't exist } catch (e) { return notFound(); } if (stats.isFile()) { var mimeType = mimeTypes[path.extname(filePath).split('.').reverse()[0]]; res.writeHead(200, { 'Content-Type': mimeType }); var fileStream = fs.createReadStream(filePath); fileStream.pipe(res); return; } return notFound(); function notFound() { res.writeHead(404, {'Content-Type': 'text/plain'}); res.write('404 Not Found: ' + filePath + '\n'); res.end(); } function busy() { res.writeHead(404, {'Content-Type': 'text/plain'}); res.write('503 Service Unavailable\n'); res.end(); } } var server = http.createServer(handleRequest); server.listen(8080, function(){ console.log('http server ready: listening on http://localhost:8080'); }); var handler = setInterval(checkButtonPress, 100); console.log('camera ready: press the button to take a picture');
カスタマイズ

このコンテンツにはカスタマイズできる項目がありません。

表示オプション
ソースコード中で変数宣言にコメントをつけるとカスタマイズ項目としてGUIウィジェットが表示されます。グレーアウトしているウィジェットはユーザが提案した項目で、ソースコード末尾の変数宣言に対応しています。

設計のダウンロード

モジュール

このプロジェクトは組み立てにモジュールを必要としません。

レイアウト
プログラム

ログインしないと使えない機能です。