WebGIS-瓦片圖灰度、倒置處理(filter)
阿新 • • 發佈:2021-10-29
以前使用百度、高德線上地圖時,可以直接配置地圖樣式。配置一些暗黑等主題的,並可以線上載入。
現在專案中都使用的是 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: '向量底圖' })
這樣處理的好處:只針對需要的圖層做處理,其他圖層、自己新增的點、線、面等要素不受影響。