WebGIS-瓦片图灰度、倒置处理(filter)

Openlayers 瓦片灰度处理

Openlayers 卷帘地图

 

以前使用百度、高德在线地图时,可以直接配置地图样式。配置一些暗黑等主题的,并可以在线加载。

现在项目中都使用的是 openlayers ,加载的地图底图基本都是瓦片形式。

系统主题色调成暗黑的,还使用以前的地图怎么感觉都是不搭配的。

 

瓦片底图都是一张张图片,可以对这些图片处理就好了。

一、filter

CSS3 的新特性 filter 可以对图片进行处理。那么直接写 css 怎么样?

经过一番查找,直接对加载地图的 canvas 设置 filter 样式就可以。

canvas {
    filter: grayscale(1) invert(1) !important;
}

在 openlayers 中对 canvas 设置了这个属性,所以要加 !important

其中 grayscale 是做灰度处理,inver  是做倒置处理。

这两个可以单独使用,也可以结合使用。根据自己主题搭配合理使用。

效果如下:

看上去效果还是比前面好不少。

问题:

在接下来有有了新问题:因为是对 canvas 做的 filter 处理,所以所有的地图、自己添加的点、线等都做了处理(这些是不想被处理的)。

寻找了一圈之后发现:openlayers 可以单独对 瓦片处理。

二、openlayers 处理

openlayers 可以对加载的任何图片做处理。主要是通过 tileLoadFunction

通过搜索API发现在 ol/source 下面的能加载图片的基本都有这个函数。如:XYZ、WMTS、Tile、BingMaps。

这个函数是在加载图片的时候对图片做了预处理。

具体代码实现如下:

      const vecLayer = new TileLayer({
        source: new XYZ({
          url: mapUrls['aMap-vec-a'],
          tileLoadFunction: function(imageTitle, src) {
            const img = new Image()
            img.crossOrigin = ''
            img.onload = () => {
              const canvas = document.createElement('canvas')
              const w = img.width
              const h = img.height
              canvas.width = w
              canvas.height = h
              const context = canvas.getContext('2d')
              context.drawImage(img, 0, 0, w, h, 0, 0, w, h)
              const imgData = context.getImageData(0, 0, w, h)
              for (let i = 0; i < imgData.height; i++) {
                for (let j = 0; j < imgData.width; j++) {
                  const x = (i * 4) * imgData.width + j * 4
                  const r = imgData.data[x]
                  const g = imgData.data[x + 1]
                  const b = imgData.data[x + 2]
                  const avg = (r + g + b) / 3
                  // 注意这里:avg 是灰度值,如果只需要灰度那就直接赋值,需要倒置(invert)的,用 255 减去灰度值
                  imgData.data[x] = imgData.data[x + 1] = imgData.data[x + 2] = 255 - avg
                }
              }
              context.putImageData(imgData, 0, 0)
              imageTitle.getImage().src = canvas.toDataURL('image/png')
            }
            img.src = src
          }
        }),
        title: '矢量底图'
      })

这样处理的好处:只针对需要的图层做处理,其他图层、自己添加的点、线、面等要素不受影响。

 

posted @ 2021-10-29 11:00  漠里  阅读(606)  评论(0编辑  收藏  举报