首页 > 解决方案 > 试图从画布上的像素数组绘制图像

问题描述

我有一个 256 个值的像素数组,看起来像这样:

[-7.440151952041672e-45, -3.549412689007182e-44, -1.6725845544560632e-43, -7.785321621854041e-43, -3.579496378208359e-42, -1.6256392941914181e-41, ...]

我想要实现的是,将此像素阵列图像绘制到画布上。我需要这个的原因是因为我需要根据卷积值重新计算像素数组,以使用特定的过滤器重绘图像。

我目前正在尝试使用以下方法绘制它:

function generate_image() {
    // create an offscreen canvas
  var canvas = document.createElement('canvas');
  canvas.setAttribute("id", "canvas_id");
  canvas.style.cssText = 'width: 400px; height: 400px; z-index: 1;';
  document.body.appendChild(canvas);
  var ctx=canvas.getContext("2d");

  var images = generate_image_array_data();

  // This is the pixel array of the image
  var image = images[2];

  var palette = ctx.getImageData(0, 0, 160, 120);

  palette.data.set(new Uint8ClampedArray(image));

  ctx.putImageData(palette, 0, 0);
}

使用上面的代码,画布上什么也没有发生。我相当肯定我做错了什么,但我不确定是什么。如果有人能够指出我正确的方向,那将不胜感激。

标签: javascriptimageimage-processingcanvascomputer-vision

解决方案


您显示的日志不能是 Uint8ClampedArray 之一。
Clamped Uint8 值不能为负数,也不能为浮点数。

因此,这些要么是 32 位浮点值,要么是 64 位浮点值。

一旦确定它是哪个,就可以通过执行将其转换为钳制的 Uint8 值

const data = new Uint8ClampedArray( original_data.buffer );

iforiginal_data已经是一个 TypedArray。

如果不是,而是一个普通的数组,您必须首先从该数组中的值重建一个 TypedArray,然后进行相同的转换。

假设 64 位浮点值:

const data = new Uint8ClampedArray( new Float64Array( images[ 2 ] ).buffer );
const palette = new ImageData( data, 160, 120 );

generate_image();

function generate_image() {
  // create an offscreen canvas
  var canvas = document.createElement('canvas');
  canvas.setAttribute("id", "canvas_id");
  canvas.style.cssText = 'width: 400px; height: 400px; z-index: 1;';
  document.body.appendChild(canvas);
  var ctx=canvas.getContext("2d");

  var images = generate_image_array_data();

  // This is the pixel array of the image
  var image = images[2];

  var data = new Uint8ClampedArray( new Float64Array( image ).buffer );
  var palette = new ImageData(data, 3,4);
  ctx.putImageData(palette, 0, 0);
  
  ctx.imageSmootingEnabled = false;
  ctx.globalCompositeOperation = "copy";
  ctx.drawImage(canvas, 0, 0, 3, 4, 0, 0, canvas.width, canvas.height);
}
function generate_image_array_data() {
  return [, , [-7.440151952041672e-45, -3.549412689007182e-44, -1.6725845544560632e-43, -7.785321621854041e-43, -3.579496378208359e-42, -1.6256392941914181e-41 ] ];
}

PS:如果您不需要画布上的像素,请不要调用 getImageData,更喜欢 ctx.createImageData(width, height) 甚至 new ImageData(width, height),这将避免您的画布位图缓冲区(缓慢)从 GPU 转移到 CPU


推荐阅读