Espruino:Примеры/Демонстрация изображения вебкамеры ПК/планшета на дисплее через Ethernet
Демонстрация изображения вебкамеры ПК/планшета на дисплее через Ethernet[1]
Введение
В современных браузерах при помощи JavaScript можно получить доступ к некоторым очень интересным функциям. Одна из них – это функция webkitGetUserMedia, позволяющая получить доступ к веб-камере компьютера (с разрешения!).
В этом примере мы воспользуемся платой Espruino для хостинга веб-страницы, которая будет получать доступ к веб-камере, а потом отправлять обратно на Espruino изображение низкого разрешения с камеры, после чего Espruino сможет показать его на LED-матрице.
Вам понадобятся
- Матрица RGB123 – я использовал 16x16.
- Модуль WIZnet W5500.
- Ноутбук/планшет с веб-камерой.
Подсоединение
- Подключите RGB123 согласно инструкциям в этой статье
- Подключите WIZnet W5500 согласно инструкциям в этой статье
Код
Итак, первый шаг – это создание веб-страницы, которая будет считывать изображение с камеры. Код ниже довольно прост, и в нём имеется лишь минимальная проверка на ошибки:
<html>
<body>
<!-- Видео-элемент, который будет содержать изображение с камеры -->
<video autoplay></video>
<!-- Холст, который будет использоваться для того, чтобы сделать изображение с веб-камеры меньше – 16x16, потому что это размер матрицы RGB123 -->
<canvas id='canvas' width='16' height='16'></canvas>
<!-- Скрипт для управления обработкой -->
<script language='javascript'>
// Инициализируем веб-камеру – см. https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getUserMedia:
if(navigator.webkitGetUserMedia!=null) {
var options = { video:true,audio:false };
navigator.webkitGetUserMedia(options,
function(stream) {
var video = document.querySelector('video');
video.src = window.webkitURL.createObjectURL(stream);
}, function(e) { console.log("error"); }
);
}
// Каждые 5 секунд...
setInterval(function() {
// Находим элементы для видео и холста:
var video = document.querySelector('video');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Меняем размер изображения с веб-камеры до 16х16 пикселей:
ctx.drawImage(video,0,0,16,16);
var data = ctx.getImageData(0,0,16,16);
// Теперь создаем строку из данных изображения.
// В принципе, есть способы и получше используемого здесь,
// т.к. здесь мы лишь записываем символ в диапазоне
// между A (ASCII-код 65) и P (ASCII-код 80)
// для красного, зелёного и синего значений каждого пикселя.
var s = "";
for(n=0; n<data.width*data.height; n++) {
s += String.fromCharCode(65+data.data[n*4+2]/16);
s += String.fromCharCode(65+data.data[n*4]/16);
s += String.fromCharCode(65+data.data[n*4+1]/16);
}
// Наконец, отправляем данные по HTTP
// при помощи «специальной» веб-страницы '/set':
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "/set?rgb="+s, false );
xmlHttp.send( null );
}, 5000);
</script>
</body>
</html>
Теперь её надо упаковать в строку, которую можно сохранить на Espruino. Можно сохранить её в файл на SD-карте, но в принципе уже само хранение веб-страницы в виде строки подразумевает, что для нормального функционирования Espruino не нужна SD-карта. Для этого я просто удалил комментарии (чтобы сэкономить память) и преобразовал файл при помощи конвертера файлов.
А это код для самой Espruino – обратите внимание на комментарии:
// Веб-страница из кода выше:
var page = "<html>\n<body>\n<video autoplay></video> \n<canvas id='canvas' width='16' height='16'></canvas> \n<script language='javascript'> \nif(navigator.webkitGetUserMedia!=null) { \n var options = { video:true,audio:false }; \n navigator.webkitGetUserMedia(options, \n function(stream) { \n var video = document.querySelector('video'); \n video.src = window.webkitURL.createObjectURL(stream); \n }, function(e) { console.log(\"error\"); } \n ); \n} \n\nsetInterval(function() {\n var video = document.querySelector('video'); \n var canvas = document.getElementById('canvas'); \n var ctx = canvas.getContext('2d'); \n ctx.drawImage(video,0,0,16,16); \n var data = ctx.getImageData(0,0,16,16); \n var s = \"\";\n for(n=0; n<data.width*data.height; n++) { \n s += String.fromCharCode(65+data.data[n*4+2]/16);\n s += String.fromCharCode(65+data.data[n*4]/16); \n s += String.fromCharCode(65+data.data[n*4+1]/16); \n } \n var xmlHttp = new XMLHttpRequest();\n xmlHttp.open( \"GET\", \"/set?rgb=\"+s, false );\n xmlHttp.send( null );\n}, 5000);\n</script>\n</body>\n</html>\n";
// Эта функция будет вызываться при каждом запросе веб-страницы:
function onPageRequest(req,res) {
res.writeHead(200, {'Content-Type': 'text/html'});
// Выясняем, какая страница была запрошена:
var rurl = url.parse(req.url,true);
if (rurl.pathname=="/") {
// Если это была главная страница, отправляем её:
res.write(page);
} else if (rurl.pathname=="/set") {
// Если это наша веб-страница '/set', создаем изображение 16х16:
var img = {
width : 16, height : 16, bpp : 24,
buffer : new Uint8Array(16*16*3)
};
// Заполняем его отправленными данными:
var s = rurl.query.rgb;
for (var i=0;i<768;i++)
img.buffer[i] = s.charCodeAt(i)-65;
// Рисуем его в буфер LED-матрицы:
leds.drawImage(img, 0, 0);
// Наконец, отправляем данные на дисплей:
leds.flip();
}
// Заканчиваем отправлять ответ нашей веб-страницы:
res.end();
}
// Настраиваем светодиоды:
SPI2.setup({baud:3200000, mosi:B15});
var leds = Graphics.createArrayBuffer(16,16,24,{zigzag:true});
leds.flip = function() { SPI2.send4bit(leds.buffer, 0b0001, 0b0011); };
leds.clear();
// Настраиваем Ethernet и наш веб-сервер:
var eth;
function onInit() {
var eth = require("WIZnet").connect();
console.log(eth.getIP());
require("http").createServer(onPageRequest).listen(80);
}
onInit();
Просто скопируйте и вставьте этот код в правую часть онлайн-IDE и кликните на Send to Espruino. Он должен начать работать незамедлительно.
При запуске будет напечатан IP-адрес Espruino, благодаря чему вы будете знать, куда надо подключиться, чтобы расшарить свою веб-камеру.
См.также
Внешние ссылки