来源:one-html-page-challengehttps://github.com/iveseenthedark/one-html-page-challenge

只用一个HTML文件就实现了显示相机图像画面到浏览器,但看不懂

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="author" content="iveseenthedark" /><meta name="viewport" content="width=device-width, initial-scale=1" /><meta name="theme-color" content="#333333" /><title>A S C I I C A M</title><style>#ascii-cam pre,body,html {width: 100vw;height: 100vh;margin: 0;}* {box-sizing: border-box;}body {overflow: hidden;background-color: #000;color: #eee;font-family: monospace;}#logo,#enable-cam-msg {transform: translate(-50%, -50%);position: absolute;left: 50%;top: 50%;}.fade {transition: opacity 0.25s ease-in-out;}#logo {line-height: 1.5;}#ascii-cam {opacity: 0;}#ascii-cam pre {position: absolute;top: 0;left: 0;overflow: hidden;line-height: 0.6;user-select: none;mix-blend-mode: screen;font-size: 1.2em;font-size: 2vh;}@media (max-height: 50em) {#ascii-cam pre {font-size: 1em;}}@media (min-height: 60em) {#ascii-cam pre {font-size: 1.2em;}}#ascii-cam #r-output {color: red;}#ascii-cam #g-output {color: #0f0;}#ascii-cam #b-output {color: #00f;}#enable-cam-msg {opacity: 0;font-size: 3rem;background-color: white;color: black;margin: 0;max-width: 50vw;white-space: pre-line;text-align: center;font-weight: 900;}#canvas,#video {display: none;}</style></head><body><pre id="logo" class="fade">__n_|_|_,_|===.-.===||  ((_))  |'==='-'==='
A S C I I C A M</pre><pre id="enable-cam-msg" class="fade">Allow access to camera to use</pre><div id="ascii-cam" class="fade"><div class="layers"><pre id="r-output"></pre><pre id="g-output"></pre><pre id="b-output"></pre></div></div><video id="video" autoplay="true"></video><canvas id="canvas" width="640" height="480"></canvas><script type="application/javascript">(() => {'use strict';let interval;let r_layer, g_layer, b_layer;const palette = [' ', '.', '-', ':', '+', '*', '=', '%', '@', '#'];const vanity = 'B Y  I V E S E E N T H E D A R K';/*** @param {*} stream*/const handle_video = stream => {const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');const video = document.getElementById('video');// Older browsers may not have srcObjectif ('srcObject' in video) {video.srcObject = stream;} else {// Avoid using this in new browsers, as it is going away.video.src = window.URL.createObjectURL(stream);}video.addEventListener('loadedmetadata', () => {window.addEventListener('resize', () => set_canvas_dimensions(video, canvas, ctx));set_canvas_dimensions(video, canvas, ctx);// Hide Logoplay_video(video, canvas, ctx);setTimeout(() => {document.getElementById('logo').style.opacity = 0;document.getElementById('ascii-cam').style.opacity = 1;}, 1000);});};/***/const handle_no_video = () => {setTimeout(() => {document.getElementById('logo').style.opacity = 0;document.getElementById('ascii-cam').style.opacity = 1;document.getElementById('enable-cam-msg').style.opacity = 1;play_random();}, 1000);};/*** @param {*} e*/const handle_error = e => {console.error('Error', e);handle_no_video();};/*** The greyscale value is calculated GREY = 0.299 * RED + 0.587 * GREEN + 0.114 * BLUE* For more information see http://en.wikipedia.org/wiki/Grayscale* @param {Array} image_data*/const fade_to_grey = pixels => pixels.map(pixel => pixel[0] * 0.299 + pixel[1] * 0.587 + pixel[2] * 0.114);/***/const play_video = (video, canvas, ctx) => {clearInterval(interval);// Buffer reversectx.drawImage(video, 0, 0, canvas.width * -1, canvas.height);// Grab viewconst dx = canvas.dataset.hoffset || 0;const dy = canvas.dataset.voffset || 0;const image_width = canvas.width - dx * 2;const image_data = ctx.getImageData(dx, dy, image_width, canvas.height - dy * 2).data;// Chunkconst channels = 4;const pixels = Array.from(Array(Math.ceil(image_data.length / channels)), (_, i) =>image_data.slice(i * channels, i * channels + channels));// Drawlet r_output = '';let g_output = '';let b_output = '';pixels.forEach((pixel, i) => {// Break for new lineif (i && i % image_width === 0) {r_output += '\n';g_output += '\n';b_output += '\n';}const b_idx = Math.floor((pixel[2] / 255.0) * (palette.length - 1));const r_idx = Math.floor((pixel[0] / 255.0) * (palette.length - 1));const g_idx = Math.floor((pixel[1] / 255.0) * (palette.length - 1));if (i && i >= image_width - vanity.length && i < image_width) {// Input vanity messager_output += vanity[vanity.length + i - image_width];g_output += vanity[vanity.length + i - image_width];b_output += palette[g_idx];} else {// Output camera datar_output += palette[r_idx];g_output += palette[g_idx];b_output += palette[b_idx];}}, this);r_layer.textContent = r_output;g_layer.textContent = g_output;b_layer.textContent = b_output;interval = setInterval(() => play_video(video, canvas, ctx), 33);};/***/const play_random = () => {clearInterval(interval);const char_dims = get_character_dimensions();const screen_dims = get_screen_dimensions(char_dims);const total_chars = Math.floor(screen_dims.char_width * screen_dims.char_height);const mid_x = Math.floor(screen_dims.char_width / 2);const mid_y = Math.floor(screen_dims.char_height / 2);let radius_sq = mid_x * mid_x + mid_y + mid_y;radius_sq = radius_sq < 2500 ? 2500 : radius_sq; // Stop the circle getting too smalllet r_output = '',g_output = '',b_output = '';for (let i = 0; i < total_chars; i++) {// Break for new lineif (i && i % screen_dims.char_width === 0) {r_output += '\n';g_output += '\n';b_output += '\n';}const char_pos_x = i % screen_dims.char_width;const char_pos_y = i / screen_dims.char_width;let dist = (char_pos_x - mid_x) * (char_pos_x - mid_x) + (char_pos_y - mid_y) * (char_pos_y - mid_y);dist = dist > radius_sq ? radius_sq : dist; // Distance can be further than radius, clampconst range = Math.floor(palette.length * (1 - dist / radius_sq));const r_idx = Math.floor(Math.random() * range);const g_idx = Math.floor(Math.random() * range);const b_idx = Math.floor(Math.random() * range);r_output += palette[r_idx];g_output += palette[g_idx];b_output += palette[b_idx];}r_layer.textContent = r_output;g_layer.textContent = g_output;b_layer.textContent = b_output;interval = setInterval(play_random, 100);};/***/const get_character_dimensions = () => {const span = document.createElement('span');span.textContent = 'X';span.style.position = 'absolute';span.style.left = '-100px';document.querySelector('#ascii-cam pre').appendChild(span);const dimensions = span.getBoundingClientRect();span.remove();return dimensions;};/***/const get_screen_dimensions = char_dims => {return {width: window.innerWidth,height: window.innerHeight,char_width: Math.ceil(window.innerWidth / char_dims.width),char_height: Math.ceil(window.innerHeight / char_dims.height)};};/***/const set_canvas_dimensions = (video, canvas, ctx) => {console.log('setting canvas dimensions');const char_dims = get_character_dimensions();const screen_dims = get_screen_dimensions(char_dims);let width = Math.floor(screen_dims.width / char_dims.width);let height = Math.max(width * 0.75, screen_dims.char_height);if (height > screen_dims.char_height) {canvas.dataset.voffset = Math.floor((height - screen_dims.char_height) / 2);canvas.dataset.hoffset = 0;} else {width = (height / 3) * 4;canvas.dataset.hoffset = Math.floor((width - screen_dims.char_width) / 2);canvas.dataset.voffset = 0;}video.width = canvas.width = width;video.height = canvas.height = height;// Reset scale if context existsctx && ctx.scale(-1, 1);};// Onloadwindow.addEventListener('load', () => {if (navigator && navigator.mediaDevices) {// Grab layersr_layer = document.getElementById('r-output');g_layer = document.getElementById('g-output');b_layer = document.getElementById('b-output');const constraints = { audio: false, video: {} };navigator.mediaDevices.getUserMedia(constraints).then(handle_video).catch(handle_error);} else {handle_no_video();}});})();</script></body>
</html>

HTML显示相机图像相关推荐

  1. Baumer工业相机堡盟相机如何使用CameraExplorer软件查看相机图像相关参数如Binning像素合并、ROI图像剪切、PixelFormat像素格式功能等

    项目场景 Baumer工业相机堡盟相机是一种高性能.高质量的工业相机,可用于各种应用场景,如物体检测.计数和识别.运动分析和图像处理. Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分 ...

  2. Ubuntu20.04 ROS读取basler相机图像步骤。MATLAB2021b标定basler单目相机

    运行环境:Ubuntu20.04(64-Bit) ROS版本:Noetic 网卡型号:Realtek RTL 8156外置网卡 相机型号:acA 1920-25gc (GigE接口) 驱动版本:pyl ...

  3. 淘宝乐视奥比中光深度摄像头不显示RGB图像终极解决办法

    我的上一篇博文的解决办法是自己添加了启动文件,能够成功显示图像了. 今天无聊看了下Astro的官方ros驱动代码,其中有一段发现如下: 可以看到这里是通过vendor向量和product ID号来确定 ...

  4. 【多传感融合】优达学城多传感融合学习笔记(三)——将激光雷达3D点云映射到相机图像(上)

    将激光雷达3D点云映射到相机图像(上)--原理分析 目录 将激光雷达3D点云映射到相机图像(上)--原理分析 齐次坐标系 内参(Intrinsic Parameters) 外参(Extrinsic P ...

  5. Baumer相机使用CameraExplorer软件采集VCXG-51M相机图像时,发现图像显示界面无任何图像现象。

    项目场景: Baumer工业相机堡盟相机是一种高性能.高质量的工业相机,可用于各种应用场景,如物体检测.计数和识别.运动分析和图像处理. Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高 ...

  6. Baumer工业相机堡盟工业相机如何通过BGAPISDK将相机图像写入相机内存(C++)

    Baumer工业相机堡盟工业相机如何通过BGAPISDK将相机图像写入相机内存(C++) Baumer工业相机 Baumer工业相机BGAPISDK和相机内存的技术背景 Baumer工业相机通过BGA ...

  7. 双目相机图像校正(五)

    本文来自公众号:机器人视觉 1.读取左右相机图像,使用Opencv和MATLAB标定结果对图像进行校正 //对焊缝图像进行校准//load imageMat img_left = imread(&qu ...

  8. 使用Python,Matplotlib显示RGB图像

    使用Python,Matplotlib显示RGB格式的 图像 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用matplotlib显示RGB图像.具体是使用matplotlib,pyplot和m ...

  9. R语言ggplot2可视化把y轴显示在图像的右侧实战: y-axis on the right

    R语言ggplot2可视化把y轴显示在图像的右侧实战: y-axis on the right 目录 R语言ggplot2可视化把y轴显示在图像的右侧实战: y-axis on the right

最新文章

  1. asp.net mvc Post上传文件大小限制 (转载)
  2. python学费多少-Python开发学费一般多少钱
  3. Flutter 15: 图解 ListView 不同样式 item 及 Widget 显隐性
  4. pusher 创建新应用_使用 Laravel-echo-server 构建实时应用
  5. 巴黎市中心降下2019年第一场雪
  6. 飞秋_飞秋2010_飞秋2010下载_飞秋下载2010正式版
  7. 刚开始学ASP+ACCESS时,该注意的事项
  8. 龙果充值平台,具备话费充值、流量充值、话费卡兑换功能;可以拓展其他充值兑换业务;也适用于支付、鉴权等业务功能的拓展。
  9. 牛客国庆集训派对Day2: E. 数据排序(状压DP+记忆化搜索)
  10. django 开发 - 小心模板文件的编码格式(utf-8)
  11. 小米mini路由器,刷openwrt,制作usb打印机服务器
  12. 微信小程序-“授权失败”场景的优雅处理
  13. 常用数字信号处理方法在matlab上的实现(目录和先导)
  14. 家中买的计算机配置,配置,教您买电脑主要看哪些配置
  15. 华为云notebook在线解压压缩包问题
  16. 人工智能史上的二次低谷——第一次低谷
  17. 安装postman工具 出现请设置注册表项HKLM\Software\Microsoft\.NETFramework\InstallRoot,指向.NET Fra
  18. 微服务拆分策略和原则
  19. 贪心算法实现最大收益
  20. 计算机开机硬盘扫描,win7系统开机自动扫描硬盘的原因及解决方法

热门文章

  1. jsp如何引入html样式,jsp怎么引入css样式?
  2. html语言怎么改变文字大小,如何设置css中字体大小?
  3. 点击tree节点,刷新表格
  4. p80 红蓝对抗-AWD 模式准备攻防监控批量
  5. Redis cache-aside模型-分布式锁等问题研究
  6. spark 逻辑回归算法案例_黄美灵的Spark ML机器学习实战
  7. ajax poi jsp,Springboot+poi无法使用ajax方法
  8. 安卓 TV 网络判断(含PPPOE) 封装
  9. 使用树莓派基于FFmpeg推流视频和摄像头到B站直播间
  10. 探秘WebMagic:爬虫神器