【问题标题】:Generate an image data-uri programmatically in javascript在 javascript 中以编程方式生成图像数据 uri
【发布时间】:2014-03-06 00:22:17
【问题描述】:

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

【问题讨论】:

  • 图像作为 data-uris 很大,画布是要走的路。
  • 大是什么意思?这只是压缩的问题吗?还是与base64编码有关?我已经根据我找到的链接中的代码实现了一个快速测试,它创建的图像大约为 70kb,这当然可以改进,但绝不是什么大不了的。创建和销毁一个画布元素,写入它,然后将其作为覆盖发送到谷歌地图,这似乎是很多开销,只需发送一个(有点长的)字符串就可以减少。

标签: javascript image data-uri


【解决方案1】:

感谢我的 stackexchange 问题中出现的侧边栏中的一些措辞,我再次尝试使用一些不同的术语进行谷歌搜索,发现:

http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/

这或多或少回答了我的问题。不过还是有兴趣的其他人有建议或答案!

更新:

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

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);

这里是 lttleEndianHex 辅助函数,取自上面的链接:

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

【讨论】:

  • 你如何将图像提供给这个?我正在寻找一种无需画布即可获取 dataURI 的方法。
  • 在我的例子中,我是基于一个数据点矩阵动态生成图像,我可以将其输入到这个函数中,以便 data-uri 字符串可以创建一个图像元素,然后可以将其输入到谷歌地图作为覆盖元素。也许您可以多解释一下您正在尝试做什么,因为听起来您是从图像开始并想要其中包含的数据,而我正在做相反的事情。
  • 感谢您提供帮助。是的,我只是想知道如何获取 HTML 图像,并将其放入 javascript 对象,然后如何将其写入 blob/file。我发现了这个叫做 FileReader 的东西。
  • 还在对输入和输出感到困惑吗? HTML图像是什么意思? 标签?将其写入文件是什么意思?在服务器上?供访客下载?以及为什么在这两种情况下都需要在 javascript 中处理图像,而不是通过服务器端处理,这在任何一种情况下都是非常必要的。为什么用户不能在浏览器中右键点击图片进行下载等...?以及为什么不想使用画布来获取图像数据。您实际上不需要在可见页面上有一个画布元素来使用这些功能。
猜你喜欢
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2015-07-29
相关资源
最近更新 更多