【问题标题】:Render image on webpage from pixel array从像素数组在网页上渲染图像
【发布时间】:2018-12-18 15:14:57
【问题描述】:

我有一个形状为 64x64x3 的 python 数组。因此 64 宽度、64 高度和 3 个 RGB 像素值。 如何在我的网站上呈现此像素阵列? 例如,有没有办法让<img> 标记读取像素数组而不是文件名?

使用 JavaScript 数组的解决方案也很好。

【问题讨论】:

    标签: javascript python web


    【解决方案1】:

    您可以使用<canvas> 元素并以编程方式呈现像素。

    The MDN has a great article on canvas 给出了一个以编程方式读取和写入像素的示例。

    var canvas = document.getElementById('rasterCanvas');
    var ctx = canvas.getContext('2d');
    
    // get current raster data
    var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var data = imageData.data;
    
    // prepare data
    for(var i = 0; i < data.length; i++) {
      data[i] = Math.random() * 255; 
    }
    
    // draw newly modified pixels back onto the canvas
    ctx.putImageData(imageData, 0, 0);
    &lt;canvas id="rasterCanvas" style="width: 100px; height: 100px; border: 1px solid red"&gt;&lt;/canvas&gt;

    【讨论】:

    • 请注意,当您传输 RGB 数组值时,我的(以及所有其他客户端方法)会受到压缩不足的影响,除非您自己压缩发送的数据。将其在服务器端呈现为可压缩格式可以节省带宽,尤其是在大型图形上。 (例如,参见 Bart 的回答)
    【解决方案2】:

    您需要先将数组保存到图像文件中,然后使用&lt;img&gt; 标签链接它。

    这是一个使用 PIL 库的示例:

    from PIL import Image
    
    imageFile = Image.new('RGB', (len(myArray[0]), len(myArray)))
    imageFile.putdata([tuple(p) for row in myArray for p in row])
    imageFile.save("example.png")
    

    【讨论】:

      【解决方案3】:

      有关基于 Javascript 的完整答案,请参见下文。我选择了HTML5 Canvas,因为它易于使用,您可以在画布上设置单个像素。

      注意:数组只有5x5x3,因为我是手工做的,但概念应该很明显。

      var ctx = document.getElementById('imageCanvas').getContext('2d');
      var imageData = [
      	[[255,0,0], [255,0,0], [255,0,0], [255,0,0], [255,0,0]],
        [[0,255,0], [0,255,0], [0,255,0], [0,255,0], [0,255,0]],
        [[255,0,0], [255,0,0], [255,0,0], [255,0,0], [255,0,0]],
        [[0,255,0], [0,255,0], [0,255,0], [0,255,0], [0,255,0]],
        [[255,0,0], [255,0,0], [255,0,0], [255,0,0], [255,0,0]],
      ];
      
      for(var y = 0; y < imageData.length; y++){
      	for(var x = 0; x < imageData[y].length; x++){
        	ctx.fillStyle = `rgb(${imageData[y][x][0]}, ${imageData[y][x][1]}, ${imageData[y][x][2]})`;
      		ctx.fillRect( x, y, 1, 1 );
        }
      }
      <canvas id="imageCanvas" width="64" height="64" style="border:1px solid #000000;">
      </canvas>

      【讨论】:

      • 我看到其他人正在使用 putImageData,这也是一个不错的选择。但是,您仍然需要将 Python 数组转换为 Javascript,因此您可以自行决定如何存储像素数组。
      • 我只是在小提琴中尝试了它,对于 1920x1080 图像,它冻结了我的浏览器超过 5 秒。 jsfiddle.net/sebi_/y1kbr80z/24 时间看控制台,大部分时间都花在了评估脚本和内部填充矩形上。
      • @Sebi 也许它对于 1920x1080 图像不是最有效的。但是,您在问题中指定您正在处理 64x64 图像。
      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 2016-06-28
      • 2012-11-27
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      相关资源
      最近更新 更多