1. 程式人生 > 其它 >WebGIS-瓦片圖灰度、倒置處理(filter)

WebGIS-瓦片圖灰度、倒置處理(filter)

以前使用百度、高德線上地圖時,可以直接配置地圖樣式。配置一些暗黑等主題的,並可以線上載入。

現在專案中都使用的是 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: '向量底圖' })

這樣處理的好處:只針對需要的圖層做處理,其他圖層、自己新增的點、線、面等要素不受影響。