在javascript中以编程方式生成图像数据uri

在javascript中以编程方式生成图像数据uri,javascript,image,data-uri,Javascript,Image,Data Uri,我正在使用谷歌地图进行一个地图项目。我们有各种不同类型的数据,这些数据以不同的地理边界显示。有些数据来自客户端,在隐私方面受到很大限制,无法发送到服务器端进行处理。我们项目的目标之一是将不同的数据集插入到一个通用的规则大小的网格中进行比较和分析。我希望能够可视化地图上的网格。网格矩阵约为120x150,因此使用单个标量值的单元格总数约为18000个。这是太多的多边形,无法使用本机Google Maps绘图进行渲染。因为它是一个规则大小的网格,所以一个好的解决方案似乎是将网格渲染为图像,并将其作为

我正在使用谷歌地图进行一个地图项目。我们有各种不同类型的数据,这些数据以不同的地理边界显示。有些数据来自客户端,在隐私方面受到很大限制,无法发送到服务器端进行处理。我们项目的目标之一是将不同的数据集插入到一个通用的规则大小的网格中进行比较和分析。我希望能够可视化地图上的网格。网格矩阵约为120x150,因此使用单个标量值的单元格总数约为18000个。这是太多的多边形,无法使用本机Google Maps绘图进行渲染。因为它是一个规则大小的网格,所以一个好的解决方案似乎是将网格渲染为图像,并将其作为单个实体覆盖在地图上。因为我无法将数据发送到服务器进行处理,所以我试图想出一种完全用javascript实现的方法。我知道可以在css中使用数据uri,我也相信javascript,将小图像存储为字符串。我不确定谷歌地图是否会接受这一点,但这将是一个单独的问题。现在我只是想知道是否有人使用数据uri模型实现了javascript图像生成器。如果是的话,怎么做。我已经搜索过了,但没有发现任何企图。我已经看过文件规范,但我想在深入钻研白鹅追逐/重新发明轮子之前,我应该在这里问一下。我知道我可以使用canvas元素以一种在代码可读性方面更有意义的方式来实现这一点,但直接生成字符串似乎是一种优雅的解决方案。

多亏了我在stackexchange问题上出现的边栏中的一些措辞,我再次尝试用一些不同的术语进行谷歌搜索,结果发现:

这或多或少回答了我的问题。但仍有兴趣的人有建议或答案

更新:

下面是我最终使用的代码。它是从上面的链接修改而来的,因此网格上的循环是从左上到右进行的,因此不需要翻转,并且我已经删除了一些辅助功能。在我的循环中,我将数据调整为以平均值为中心,并标准化为4个标准差(两个正,两个负)


图像作为数据URI很大,拉票是一种方式。你说的大是什么意思?这只是压缩的问题吗?或者它与base64编码有关?我已经根据我找到的链接中的代码实现了一个快速测试,它创建的图像大约为70kb,这当然可以改进,但也不是什么大问题。创建和销毁画布元素,对其进行写入,然后将其作为覆盖图发送到google maps,这似乎是一个很大的开销,只需发送一个(有点长的)字符串就可以省去。如何将图像提供给这个元素?我正在寻找一种不需要画布就可以获取dataURI的方法。在我的例子中,我是基于数据点矩阵动态生成图像的,我可以将这些数据点输入到这个函数中,这样数据uri字符串就可以创建一个图像元素,然后作为覆盖元素输入google maps。也许你可以再解释一下你想做什么,因为听起来你是从一个图像开始的,想要它包含的数据,而我正好相反。谢谢你的帮助。是的,我只是想知道如何获取一个HTML图像,并将其放入javascript对象,然后如何将其写入blob/file。我发现了一个叫做FileReader的东西。你的输入和输出还不清楚吗?你所说的HTML图像是什么意思?标签?你把它写进文件是什么意思?在服务器上?供访问者下载?为什么在这两种情况下都需要用javascript处理图像,而不是通过服务器端处理图像,这在这两种情况下都是非常必要的。为什么用户不能在浏览器中右键单击图像进行下载等。。。?你为什么不想用画布来获取图像数据呢。要使用这些函数,您不需要在可见页面上实际具有canvas元素。
var interpolation = this.interpolateGeoDataLayerToGrid();

var numFileBytes = this.getLittleEndianHex(interpolation.grid[0].length * interpolation.grid.length);
var w = this.getLittleEndianHex(interpolation.grid[0].length);
var h = this.getLittleEndianHex(interpolation.grid.length);

var header =
    'BM' +                    // Signature
    numFileBytes +            // size of the file (bytes)*
    '\x00\x00' +              // reserved
    '\x00\x00' +              // reserved
    '\x36\x00\x00\x00' +      // offset of where BMP data lives (54 bytes)
    '\x28\x00\x00\x00' +      // number of remaining bytes in header from here (40 bytes)
    w +                       // the width of the bitmap in pixels*
    h +                       // the height of the bitmap in pixels*
    '\x01\x00' +              // the number of color planes (1)
    '\x20\x00' +              // 32 bits / pixel
    '\x00\x00\x00\x00' +      // No compression (0)
    '\x00\x00\x00\x00' +      // size of the BMP data (bytes)*
    '\x13\x0B\x00\x00' +      // 2835 pixels/meter - horizontal resolution
    '\x13\x0B\x00\x00' +      // 2835 pixels/meter - the vertical resolution
    '\x00\x00\x00\x00' +      // Number of colors in the palette (keep 0 for 32-bit)
    '\x00\x00\x00\x00';       // 0 important colors (means all colors are important)

var imgdata = "";

for (var row=interpolation.grid.length-1; row >= 0; row--) {
    for (var col=0; col<interpolation.grid[row].length; col++) {
        var value = Math.min(255,Math.max(0,Math.floor(128 + 64*(interpolation.grid[row][col]-interpolation.mean)/interpolation.stdev)));
        imgdata += String.fromCharCode(255-value, 0, value, 128);
    }
}

var datauri = 'data:image/bmp;base64,';
if(window.btoa != undefined) {
  datauri += btoa(header + imgdata);
}
else {
  datauri += $.base64.encode(header + imgdata);
}

newOverlay = new google.maps.GroundOverlay(datauri,
      new google.maps.LatLngBounds(
          new google.maps.LatLng(this.GridDataSettings.latmin, this.GridDataSettings.longmin),
          new google.maps.LatLng(this.GridDataSettings.latmax, this.GridDataSettings.longmax)
));

newOverlay.setMap(map);
getLittleEndianHex: function(value) {
  var result = [];   
  for (var bytes = 4; bytes > 0; bytes--) {
    result.push(String.fromCharCode(value & 255));
    value >>= 8;
  }
  return result.join('');
}