[leaflet]クライアントサイドでの画像処理を可能にする「tilefilter」プラグイン
Home · humangeo/leaflet-tilefilter Wiki
「tilefilter」プラグインは、leafletにて読み込んだタイル画像をブラウザに描画される前にフックし、クライアントサイドにて画像処理が行えるようにするプラグインです。
このプラグインでは「Canvasフィルター」と「CSSフィルター」の二種類の方法で画像処理を行うことができます。
インストール
leaflet.js読み込み後にTileLayer.Filter.jsを読み込んでください。
1 2 |
<script src="leaflet.js"></script> <script src="TileLayer.Filter.js"></script> |
canvasフィルター
タイル画像をいったんcanvasへと転写し、Image Processingを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var hogeLayer = new L.TileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png', { attribution: '地理院タイル', filter: function () { new L.CanvasFilter(this, { channelFilter: function (imageData) { // 画像処理を行う return imageData; } }).render(); } }); |
channelFilterの引数に、タイル画像をcanvasに転写した際のImageData Objectが送られます。
このImageData Objectに対して処理を行うことで様々なフィルタ効果を付加させることができます。
前回の記事では、地理院タイル(電子国土基本図)を読み込み、エッジを抽出しエッジ(白色)以外の透明度を0にしてオーバーレイしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
var edgeLayer = new L.TileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png', { attribution: '地理院タイル(標準地図エッジ)', filter: function () { new L.CanvasFilter(this, { channelFilter: function (imageData) { edge(imageData.data); return imageData; } }).render(); } }); function edge(data) { var length = data.length; var width = 256, height = 256; var gray = new Uint8ClampedArray(data.length); toGray(data, gray); var edge = new Uint8ClampedArray(data.length); for (var y = 0; y < height - 1; y++) { for (var x = 0; x < width - 1; x++) { var i = x + y * width; var r_i = (x + 1) + y * width; var ex = gray[r_i] - gray[i]; var d_i = x + (y + 1) * width; var ey = gray[d_i] - gray[i]; var ez = Math.sqrt(ex * ex + ey * ey); edge[i] = ez * 2; } } toColor(edge, data); } function toGray(rgba, gray) { var length = rgba.length; var total = 0; for (var i = 0; i < length; i += 4) { var g = 0.30 * rgba[i + 0] + 0.59 * rgba[i + 1] + 0.11 * rgba[i + 2]; gray[i/4] = g; total += g; } return total / (length / 4); } function toColor(gray, rgba) { var length = gray.length * 4; for (var i = 0; i < length; i += 4) { rgba[i + 0] = gray[i/4]; rgba[i + 1] = gray[i/4]; rgba[i + 2] = gray[i/4]; if (gray[i/4] > 180){ rgba[i + 3] = 255; }else{ rgba[i + 3] = 0; } } } |
ビルトインフィルター
canvasフィルターには、いくつかの組み込みフィルターが用意されています。
以下は、セピア効果を付加するフィルター
1 2 3 4 5 6 7 8 9 |
var baseLayer = new L.TileLayer('http://otile1.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg', { filter: function () { new L.CanvasFilter(this, { channelFilter: function (imageData) { return new L.CanvasChannelFilters.Sepia(imageData).render(); } }).render(); } }); |
CSSフィルター
ブラウザのCSSフィルター機能を使ってタイル画像にフィルター効果を付加します。Chromeなどブラウザでは、CSSでのフィルター効果がGPUによってアクセラレーションレンダリングされるため、単純な画像処理であればcanvasでImageDataを弄るより高速に描画されます。
※Webkit系ブラウザ以外ではCSS Filterに対応していない場合が多数あります。
1 2 3 4 5 6 7 8 |
var ort = new L.TileLayer('http://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg', { attribution: '地理院タイル(オルソ画像)', filter:function () { new L.CSSFilter(this, { filters: //cssフィルタープロパティを指定 }).render(); } }); |
サンプル
下記はcssフィルターの「invert」コマンドを使ってタイル画像に対して階調の反転を行ったサンプルです。
1 2 3 4 5 6 7 8 |
var ort = new L.TileLayer('http://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg', { attribution: '地理院タイル(オルソ画像)', filter:function () { new L.CSSFilter(this, { filters:['invert(100%)'] }).render(); } }); |
cssフィルタープロパティは複数指定可能です。