【问题标题】:How to get usable canvas from Mapbox GL JS如何从 Mapbox GL JS 获取可用的画布
【发布时间】:2018-04-12 23:39:07
【问题描述】:

我正在使用Mapbox GL,并尝试获取它的快照,并将快照与另一个叠加的图像合并以进行输出。

我在屏幕外有一个HTMLCanvasElement,我首先将Map.getCanvas() 返回的画布写入它,然后在其上写入第二个(alpha 透明)画布。

问题是,虽然我在 Map 实例中清楚地看到屏幕上的元素,但结果只显示了第二个写入的图像/画布,其余的都是空白的。

所以我只导出地图的画布,我发现这是因为地图画布是空白的,尽管 console.log() 显示其中的图像数据是一大块信息。

这是我的导出函数:

  onExport(annotationCanvas: HTMLCanvasElement) {

    const mergeCanvas: HTMLCanvasElement = document.createElement('canvas');
    const mapCanvas: HTMLCanvasElement = this.host.map.getCanvas();
    const mergeCtx: CanvasRenderingContext2D = mergeCanvas.getContext('2d');

    mergeCanvas.height = annotationCanvas.height;
    mergeCanvas.width = annotationCanvas.width;
    mergeCtx.drawImage(mapCanvas, 0, 0);
    mergeCtx.drawImage(annotationCanvas, 0, 0);

    const mergedDataURL = mergeCanvas.toDataURL();
    const mapDataURL = mapCanvas.toDataURL();
    const annotationDataURL = annotationCanvas.toDataURL();

    console.log(mapDataURL); // Lots of data

    download(mapDataURL, 'map-data-only.png'); // Blank image @ 1920x1080
    download(mergedDataURL, 'annotation.png'); // Only shows annotation (the second layer/canvas) data

  }

这是一个错误,还是我遗漏了什么?

更新:我有点明白这是怎么回事,并且有可能的选择。

在偶然发现Mapbox feature request 时,我了解到如果您实例化您的Map 并将preserveDrawingBuffer 选项设置为false(默认值),您将无法获得具有可用图像数据的画布。但是将此选项设置为true 会降低性能。但是在 Map 实例化后,您无法更改此设置...

我希望地图尽可能发挥最佳性能!!!

所以,在this answer我偶然发现了一个关于three.js的问题,我了解到如果我在渲染后立即截取屏幕截图,我将获得我需要的画布/数据。

我尝试在捕获画布之前调用this.host.map['_rerender'](),但它仍然返回空白。

然后在源代码中搜索,我发现了一个名为_requestRenderFrame 的函数,看起来它可能是我需要的,因为我可以要求 Map 在下一个渲染周期后立即运行一个函数。但当我发现,出于某种原因,该函数是omitted in the compiled code, whilst present in the source,显然是因为它只在主版本中,而不是版本的一部分。

所以我还没有一个令人满意的解决方案,所以请让我知道任何见解。

【问题讨论】:

  • 你在 Mapbox GL JS master 中尝试过 _requestRenderFrame 吗?
  • 我还没试过。
  • 您有解决方案了吗?我遇到了同样的问题。
  • 我不记得结果了。我将从 Andew Harvey 的回答开始。如果可行,请在此处发布作为解决方案。

标签: javascript canvas html5-canvas mapbox mapbox-gl-js


【解决方案1】:

正如您在更新的问题中提到的,解决方案是在地图初始化时设置 preserveDrawingBuffer: true

为了回答您更新的问题,我认为@jfirebaugh 在https://github.com/mapbox/mapbox-gl-js/issues/6448#issuecomment-378307311 的回答总结得很好:

preserveDrawingBuffer 不能即时修改。它必须在创建 WebGL 上下文时设置,这会对性能产生负面影响。

传闻可以在渲染后立即获取画布数据URL,不需要preserveDrawingBuffer,但我没有验证过,我怀疑规范不保证。

因此,虽然有可能在渲染后立即获取画布数据 URL,但规范并不能保证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2020-08-14
    相关资源
    最近更新 更多