简体   繁体   English

在 canvas 上渲染一个 rgb 像素数组

[英]Render an array of rgb pixels on a canvas

I have this problem, I have a socket that sends me packets each one containing a row of a frame.我有这个问题,我有一个套接字向我发送数据包,每个数据包都包含一行帧。 Using python I reconstruct the full-frame as an array of RBG pixels.使用 python,我将全帧重建为 RBG 像素阵列。 How can I render that array of pixels on a canvas, using WebGL or something similar?如何使用 WebGL 或类似工具在 canvas 上渲染该像素数组?

With Python SDL2 was pretty easy, now I need to do the same on a webpage.使用 Python SDL2 非常简单,现在我需要在网页上做同样的事情。

Given RGBA data of the form [[123,32,40,255], [3,233,42,120], ...] , this will return a canvas with that data:给定[[123,32,40,255], [3,233,42,120], ...]形式的 RGBA 数据,这将返回带有该数据的 canvas:

function createCanvasFromRGBAData(data, width, height) {
  // `data` should look something like [[123,32,40,255], [3,233,42,120], ...]
  if(width*height !== data.length) throw new Error("width*height should equal data.length");
  let canvas = document.createElement("canvas");
  canvas.width = width;
  canvas.height = height;
  let ctx = canvas.getContext("2d");
  let imgData = ctx.createImageData(width, height);
  for(let i = 0; i < data.length; i++) {
    imgData.data[i*4+0] = data[i][0];
    imgData.data[i*4+1] = data[i][1];
    imgData.data[i*4+2] = data[i][2];
    imgData.data[i*4+3] = data[i][3];
  }
  ctx.putImageData(imgData, 0, 0);
  return canvas;
}

I found an interesting way to render ONE pixel here: What's the best way to set a single pixel in an HTML5 canvas?我在这里找到了一种渲染 ONE 像素的有趣方法: 在 HTML5 画布中设置单个像素的最佳方法是什么?

I don't think there is a way in vanilla JavaScript to render a single pixel at a time, but the library p5.js (that I use a lot) does have this functionality.我认为 vanilla JavaScript 中没有办法一次渲染一个像素,但是库 p5.js(我经常使用)确实具有此功能。

A few other ways would be to 1) Just have a 1x1 square render (acting as a pixel).其他一些方法是 1) 只需一个 1x1 方形渲染(充当像素)。 2) Use 1x1 images like in the stackoverflow link above. 2) 使用 1x1 图像,如上面的 stackoverflow 链接。

EDIT:编辑:

I found anouther stackoverflow about this and apparently I was wrong about vanilla JavaScript: Drawing a dot on HTML5 canvas我发现了关于这个的另一个stackoverflow,显然我对香草JavaScript错了: 在HTML5画布上绘制一个点

Here is my new and improved answer:这是我的新的和改进的答案:

The problem is you cant load the pixels very fast, rendering them is the easy part.问题是你不能非常快地加载像素,渲染它们是很容易的部分。 So why not reuse already loaded pixels?那么为什么不重用已经加载的像素呢? What I've created is an automated way to load an array of pixels and save them to be rendered later.我创建的是一种自动加载像素数组并将它们保存以供以后渲染的方法。 Here's the not-to-optimized code:这是未优化的代码:

 let render; let pixelArray; function setup() { createCanvas(640, 480); render = new renderPixels(); pixelArray = Array(width*height).fill(0); pixelArray = pixelArray.map( r => {return color(random(255), random(255), random(255)) }); render.newImage("random", pixelArray, height, width); pixelArray = pixelArray.map( r => {return color(random(255), random(255), random(255)) }); render.newImage("random2", pixelArray, height, width); pixelArray = pixelArray.map( r => {return color(random(255), random(255), random(255)) }); render.newImage("random3", pixelArray, height, width); frameRate(5) //<-- Decrease to see full potential } function draw() { background(220); if(frameCount % 3 == 0){ render.loadImage(0, 0, "random"); } else if(frameCount % 3 == 1){ render.loadImage(0, 0, "random2"); } else { render.loadImage(0, 0, "random3"); } } class renderPixels { constructor(){ this.loadedImages = {} } newImage(name, arr, height, width){ let img = createImage(height, width); img.loadPixels(); for(let p = 0; p < (4 * height * width); p+=4){ const l = arr[p/4].levels; img.pixels[p] = l[0]; img.pixels[p+1] = l[1]; img.pixels[p+2] = l[2]; img.pixels[p+3] = l[3]; } img.updatePixels(); this.loadedImages[name] = img; } loadImage(x, y, name){ image(this.loadedImages[name], x, y); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.8/p5.min.js"></script>
I could make this into vanilla JavaScript if you like, but I need to know the format of array of RGB pixels you talk about. 如果你愿意,我可以把它变成普通的 JavaScript,但我需要知道你所说的 RGB 像素数组的格式。 Currently I'm using P5.js's color() function (which isn't very optimized) and it's working well enough. 目前我正在使用 P5.js 的color()函数(不是很优化),它运行得很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM