1 | goog.require('ol.Map');
|
2 | goog.require('ol.View');
|
3 | goog.require('ol.layer.Tile');
|
4 | goog.require('ol.proj');
|
5 | goog.require('ol.source.BingMaps');
|
6 |
|
7 | var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
|
8 |
|
9 | var imagery = new ol.layer.Tile({
|
10 | source: new ol.source.BingMaps({key: key, imagerySet: 'Aerial'})
|
11 | });
|
12 |
|
13 | var map = new ol.Map({
|
14 | layers: [imagery],
|
15 | target: 'map',
|
16 | view: new ol.View({
|
17 | center: ol.proj.fromLonLat([-120, 50]),
|
18 | zoom: 6
|
19 | })
|
20 | });
|
21 |
|
22 | var kernels = {
|
23 | none: [
|
24 | 0, 0, 0,
|
25 | 0, 1, 0,
|
26 | 0, 0, 0
|
27 | ],
|
28 | sharpen: [
|
29 | 0, -1, 0,
|
30 | -1, 5, -1,
|
31 | 0, -1, 0
|
32 | ],
|
33 | sharpenless: [
|
34 | 0, -1, 0,
|
35 | -1, 10, -1,
|
36 | 0, -1, 0
|
37 | ],
|
38 | blur: [
|
39 | 1, 1, 1,
|
40 | 1, 1, 1,
|
41 | 1, 1, 1
|
42 | ],
|
43 | shadow: [
|
44 | 1, 2, 1,
|
45 | 0, 1, 0,
|
46 | -1, -2, -1
|
47 | ],
|
48 | emboss: [
|
49 | -2, 1, 0,
|
50 | -1, 1, 1,
|
51 | 0, 1, 2
|
52 | ],
|
53 | edge: [
|
54 | 0, 1, 0,
|
55 | 1, -4, 1,
|
56 | 0, 1, 0
|
57 | ]
|
58 | };
|
59 |
|
60 | function normalize(kernel) {
|
61 | var len = kernel.length;
|
62 | var normal = new Array(len);
|
63 | var i, sum = 0;
|
64 | for (i = 0; i < len; ++i) {
|
65 | sum += kernel[i];
|
66 | }
|
67 | if (sum <= 0) {
|
68 | normal.normalized = false;
|
69 | sum = 1;
|
70 | } else {
|
71 | normal.normalized = true;
|
72 | }
|
73 | for (i = 0; i < len; ++i) {
|
74 | normal[i] = kernel[i] / sum;
|
75 | }
|
76 | return normal;
|
77 | }
|
78 |
|
79 | var select = document.getElementById('kernel');
|
80 | var selectedKernel = normalize(kernels[select.value]);
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 | select.onchange = function() {
|
87 | selectedKernel = normalize(kernels[select.value]);
|
88 | map.render();
|
89 | };
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 | imagery.on('postcompose', function(event) {
|
96 | convolve(event.context, selectedKernel);
|
97 | });
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 | function convolve(context, kernel) {
|
107 | var canvas = context.canvas;
|
108 | var width = canvas.width;
|
109 | var height = canvas.height;
|
110 |
|
111 | var size = Math.sqrt(kernel.length);
|
112 | var half = Math.floor(size / 2);
|
113 |
|
114 | var inputData = context.getImageData(0, 0, width, height).data;
|
115 |
|
116 | var output = context.createImageData(width, height);
|
117 | var outputData = output.data;
|
118 |
|
119 | for (var pixelY = 0; pixelY < height; ++pixelY) {
|
120 | var pixelsAbove = pixelY * width;
|
121 | for (var pixelX = 0; pixelX < width; ++pixelX) {
|
122 | var r = 0, g = 0, b = 0, a = 0;
|
123 | for (var kernelY = 0; kernelY < size; ++kernelY) {
|
124 | for (var kernelX = 0; kernelX < size; ++kernelX) {
|
125 | var weight = kernel[kernelY * size + kernelX];
|
126 | var neighborY = Math.min(
|
127 | height - 1, Math.max(0, pixelY + kernelY - half));
|
128 | var neighborX = Math.min(
|
129 | width - 1, Math.max(0, pixelX + kernelX - half));
|
130 | var inputIndex = (neighborY * width + neighborX) * 4;
|
131 | r += inputData[inputIndex] * weight;
|
132 | g += inputData[inputIndex + 1] * weight;
|
133 | b += inputData[inputIndex + 2] * weight;
|
134 | a += inputData[inputIndex + 3] * weight;
|
135 | }
|
136 | }
|
137 | var outputIndex = (pixelsAbove + pixelX) * 4;
|
138 | outputData[outputIndex] = r;
|
139 | outputData[outputIndex + 1] = g;
|
140 | outputData[outputIndex + 2] = b;
|
141 | outputData[outputIndex + 3] = kernel.normalized ? a : 255;
|
142 | }
|
143 | }
|
144 | context.putImageData(output, 0, 0);
|
145 | }
|