Espruino:Примеры/Демонстрация изображения вебкамеры ПК/планшета на дисплее через Ethernet: различия между версиями
Myagkij (обсуждение | вклад) (Новая страница: «{{Espruino/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} =<ref>[ www.espruino.com - ]</ref>= <syntaxhighligh...») |
Нет описания правки |
||
(не показаны 4 промежуточные версии 2 участников) | |||
Строка 3: | Строка 3: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=<ref>[ www.espruino.com - ]</ref>= | =Демонстрация изображения вебкамеры ПК/планшета на дисплее через Ethernet<ref>[https://www.espruino.com/Ethernet+Webcam www.espruino.com - Ethernet Webcam Display]</ref>= | ||
[https://www.espruino.com/Ethernet+Webcam Ethernet Webcam Matrix] | |||
==Введение== | |||
В современных браузерах при помощи [[JavaScript]] можно получить доступ к некоторым очень интересным функциям. Одна из них – это функция webkitGetUserMedia, позволяющая получить доступ к веб-камере компьютера (с разрешения!). | |||
В этом примере мы воспользуемся платой [[Espruino]] для хостинга веб-страницы, которая будет получать доступ к веб-камере, а потом отправлять обратно на [[Espruino]] изображение низкого разрешения с камеры, после чего [[Espruino]] сможет показать его на LED-матрице. | |||
==Вам понадобятся== | |||
* Матрица [https://www.espruino.com/RGB123 RGB123] – я использовал 16x16. | |||
* Модуль [https://www.espruino.com/WIZnet WIZnet W5500]. | |||
* Ноутбук/планшет с веб-камерой. | |||
== Подсоединение == | |||
* Подключите [[RGB123]] согласно инструкциям в [https://www.espruino.com/RGB123 этой статье] | |||
* Подключите [[WIZnet W5500]] согласно инструкциям в [https://www.espruino.com/WIZnet этой статье] | |||
== Код == | |||
Итак, первый шаг – это создание веб-страницы, которая будет считывать изображение с камеры. Код ниже довольно прост, и в нём имеется лишь минимальная проверка на ошибки: | |||
<syntaxhighlight lang="html5"> | |||
<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> | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Теперь её надо упаковать в строку, которую можно сохранить на [[Espruino]]. Можно сохранить её в файл на SD-карте, но в принципе уже само хранение веб-страницы в виде строки подразумевает, что для нормального функционирования [[Espruino]] не нужна [[SD-карта]]. Для этого я просто удалил комментарии (чтобы сэкономить память) и преобразовал файл при помощи конвертера файлов. | |||
А это код для самой [[Espruino]] – обратите внимание на комментарии: | |||
<syntaxhighlight lang="javascript"> | |||
// Веб-страница из кода выше: | |||
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(); | |||
</syntaxhighlight> | |||
Просто скопируйте и вставьте этот код в правую часть онлайн-IDE и кликните на '''Send to Espruino'''. Он должен начать работать незамедлительно. | |||
При запуске будет напечатан [[IP-адрес]] [[Espruino]], благодаря чему вы будете знать, куда надо подключиться, чтобы расшарить свою веб-камеру. | |||
=См.также= | =См.также= | ||
=Внешние ссылки= | =Внешние ссылки= | ||
Строка 18: | Строка 142: | ||
<references /> | <references /> | ||
{{Навигационная таблица/Espruino | {{Навигационная таблица/Портал/Espruino}} | ||
Текущая версия от 15:06, 20 мая 2023
Демонстрация изображения вебкамеры ПК/планшета на дисплее через 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, благодаря чему вы будете знать, куда надо подключиться, чтобы расшарить свою веб-камеру.
См.также
Внешние ссылки