美文网首页
七章-81-图像滤镜

七章-81-图像滤镜

作者: 彩云飘过 | 来源:发表于2020-03-27 17:55 被阅读0次

    本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers 5.3.x api。

    源码 见 1081.html ,对应的 官网示例

    image.png

    核心技术点:
    layer.on('postcompose', function(event) {})
    绑定了layer的'postcompose'事件,并在渲染后进行图像的处理

    image.png
    <!DOCTYPE html>
    <html>
    
    <head>
     <title>图像滤镜</title>
     <link rel="stylesheet" href="../include/ol.css" type="text/css" />
     <script src="../include/ol.js"></script>
    </head>
    <style></style>
    
    <body>
     <select id="kernel" name="kernel">
       <option>none</option>
       <option selected>sharpen锐化</option>
       <option value="sharpenless">sharpen less轻度锐化</option>
       <option>blur模糊</option>
       <option>shadow阴影</option>
       <option>emboss浮雕</option>
       <option value="edge">edge detect边缘查找</option>
     </select>
     <div id="map" class="map"></div>
     <div id="info">&nbsp;</div>
     <script>
       var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
    
       var imagery = new ol.layer.Tile({
         source: new ol.source.OSM()
       });
    
       var map = new ol.Map({
         layers: [imagery],
         target: 'map',
         view: new ol.View({
           center: ol.proj.fromLonLat([-120, 50]),
           zoom: 6
         })
       });
    
       var kernels = {
         none: [
           0, 0, 0,
           0, 1, 0,
           0, 0, 0
         ],
         sharpen: [
           0, -1, 0,
           -1, 5, -1,
           0, -1, 0
         ],
         sharpenless: [
           0, -1, 0,
           -1, 10, -1,
           0, -1, 0
         ],
         blur: [
           1, 1, 1,
           1, 1, 1,
           1, 1, 1
         ],
         shadow: [
           1, 2, 1,
           0, 1, 0,
           -1, -2, -1
         ],
         emboss: [
           -2, 1, 0,
           -1, 1, 1,
           0, 1, 2
         ],
         edge: [
           0, 1, 0,
           1, -4, 1,
           0, 1, 0
         ]
       };
    
       // 图像处理的方法,归一化
       function normalize(kernel) {
         var len = kernel.length;
         var normal = new Array(len);
         var i, sum = 0;
         for (i = 0; i < len; ++i) {
           sum += kernel[i];
         }
         if (sum <= 0) {
           normal.normalized = false;
           sum = 1;
         } else {
           normal.normalized = true;
         }
         for (i = 0; i < len; ++i) {
           normal[i] = kernel[i] / sum;
         }
         return normal;
       }
    
       var select = document.getElementById('kernel');
       var selectedKernel = normalize(kernels[select.value]);
    
    
    
       // map 和layers 都可以触发postcompose
       /**
        * 更新kernel并且在选项更改时重新归一化.
        */
       select.onchange = function () {
         selectedKernel = normalize(kernels[select.value]);
         map.render();//归一化之后,重新渲染地图
       };
    
    
       /**
        *在"postcompose" 触发之后应用滤镜.
        */
       imagery.on('postcompose', function (event) {
         convolve(event.context, selectedKernel);//卷积操作,应用滤镜效果
       });
    
    
       /**
        * Apply a convolution kernel to canvas.  This works for any size kernel, but
        * performance starts degrading above 3 x 3.
        * @param {CanvasRenderingContext2D} context Canvas 2d context.
        * @param {Array<number>} kernel Kernel.
        * 此处是卷积操作
        */
       function convolve(context, kernel) {
         var canvas = context.canvas;
         var width = canvas.width;
         var height = canvas.height;
    
         var size = Math.sqrt(kernel.length);
         var half = Math.floor(size / 2);
    
         var inputData = context.getImageData(0, 0, width, height).data;
    
         var output = context.createImageData(width, height);
         var outputData = output.data;
    
         for (var pixelY = 0; pixelY < height; ++pixelY) {
           var pixelsAbove = pixelY * width;
           for (var pixelX = 0; pixelX < width; ++pixelX) {
             var r = 0, g = 0, b = 0, a = 0;
             for (var kernelY = 0; kernelY < size; ++kernelY) {
               for (var kernelX = 0; kernelX < size; ++kernelX) {
                 var weight = kernel[kernelY * size + kernelX];
                 var neighborY = Math.min(
                   height - 1, Math.max(0, pixelY + kernelY - half));
                 var neighborX = Math.min(
                   width - 1, Math.max(0, pixelX + kernelX - half));
                 var inputIndex = (neighborY * width + neighborX) * 4;
                 r += inputData[inputIndex] * weight;
                 g += inputData[inputIndex + 1] * weight;
                 b += inputData[inputIndex + 2] * weight;
                 a += inputData[inputIndex + 3] * weight;
               }
             }
             var outputIndex = (pixelsAbove + pixelX) * 4;
             outputData[outputIndex] = r;
             outputData[outputIndex + 1] = g;
             outputData[outputIndex + 2] = b;
             outputData[outputIndex + 3] = kernel.normalized ? a : 255;
           }
         }
         context.putImageData(output, 0, 0);
       }
    
     </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

          本文标题:七章-81-图像滤镜

          本文链接:https://www.haomeiwen.com/subject/amvluhtx.html