重新着色 Leaflet 中图像叠加层中特定颜色的所有像素

问题描述 投票:0回答:1

我有一张大约 8000x4000 像素的图像。该图像被分解成颜色斑点。

这是图像部分的示例,以显示其外观:

我可以使用传单非常简单地绘制图像:

var map = L.map('map', {
    crs: L.CRS.Simple,
    minZoom: -2
});

var bounds = [[0,0], [3616,8192]];

var provinces = L.imageOverlay(
    'myimage.png', 
    bounds, 
    {opacity: 0.7}
).addTo(map);

我有一个用于重新着色图像的翻译,我想用它来将特定颜色的所有像素转换为不同特定颜色的像素。这就是我需要帮助的问题。

var colour_mapping = {'#4287f5':'#42f5ef', '#a3911c':'#de3510', ...}

我已经看到了有关堆栈溢出的答案,详细说明了如何更改画布的特定像素,但我不知道如何最好地在 Leaflet 中实现效果。

如何将 PNG 中特定 RGB 的所有像素替换为 javascript 中的另一个 RGB?

javascript html colors leaflet html5-canvas
1个回答
0
投票

由于您已经认为自己能够“即时”操作图像,因此您必须首先将其绘制到 html

<canvas>
元素上。另一方面,Leaflet 的
imageOverlay()
方法需要一个指向实际图像的 URL - 因此单独操作的画布不会给你带来太大的帮助。

不过还是有希望的。画布对象提供了一个名为

toDataURL()
的方法,该方法返回可以输入到
imageOverlay()
中的内容。

让我们分解一下您需要做什么:

  1. 创建一个空图像并用它来加载您的地图
  2. 如果图像加载完成,请创建一个图像大小的画布
  3. 将图像绘制到画布上
  4. 循环通过
    ctx.getImageData()
    获得的画布图像数据。这将为画布中的每个像素返回大量红色、绿色、蓝色和 alpha 值。由于您的
    colour_mapping
    数组由十六进制值组成,例如#4dc8c8,我们首先需要将 RGB 值转换为十六进制,以便能够在数组中查找匹配项。如果我们找到匹配项,则获取替换颜色并将十六进制值转换为 rgb 以最终更改颜色。
  5. 使用
    toDataURL()
    获取数据URL,最后调用
    imageOverlay()

这是一个展示用白色替换两种颜色的示例:

var map = L.map('map').setView([0.5, 0.5], 9);


var imageUrl = './js/UAZyt.png';
imageUrl = "https://corsproxy.io/?https://i.stack.imgur.com/UAZyt.png"
let image = new Image();
image.crossOrigin = "anonymous"
image.onload = (e) => {
  imageBounds = [
    [0, 0],
    [1, 1]
  ];

  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");
  canvas.width = e.target.naturalWidth;
  canvas.height = e.target.naturalHeight;
  ctx.drawImage(e.target, 0, 0);
  let colour_mapping = {
    '#4dc8c8': '#ffffff',
    '#be8eff': '#ffffff'
  };

  let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  let r, g, b, hex, hex2;
  for (let a = 0; a < imageData.data.length; a += 4) {
    r = imageData.data[a];
    g = imageData.data[a + 1];
    b = imageData.data[a + 2];
    hex = "#" + ((r << 16) | (g << 8) | b).toString(16);
    if (colour_mapping[hex]) {
      hex2 = colour_mapping[hex].match(/[0-9a-f]{2}/g);
      imageData.data[a] = parseInt(hex2[0], 16);
      imageData.data[a + 1] = parseInt(hex2[1], 16);
      imageData.data[a + 2] = parseInt(hex2[2], 16);
    }
  }
  ctx.putImageData(imageData, 0, 0);
  L.imageOverlay(canvas.toDataURL(), imageBounds).addTo(map);
}
image.src = imageUrl;
#map {
  height: 360px;
}
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<div id="map"></div>

© www.soinside.com 2019 - 2024. All rights reserved.