Color Manipulation——颜色操作

来源:互联网 发布:淘宝开店交费吗 编辑:程序博客网 时间:2024/06/06 17:23

A raster source allows arbitrary manipulation of pixel values. In this example, RGB values on the input tile source are adjusted in a pixel-wise operation before being rendered with a second raster source. The raster operation takes pixels in in RGB space, converts them to HCL color space, adjusts the values based on the controls above, and then converts them back to RGB space for rendering.
栅格数据源允许对像素值的任意操作。在这个例子中,输入瓦片数据源的RGB值可以在用第二个栅格数据源渲染之前的逐像素操作中进行调整。栅格操作把RGB空间中的像素转换为HCL颜色空间,基于上面的控件进行调整,然后把它们在渲染之前转换回RGB空间进行渲染。

代码:
<!DOCTYPE html><html>  <head>    <title>Color Manipulation</title>    <link rel="stylesheet" href="https://openlayers.org/en/v4.2.0/css/ol.css" type="text/css">    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>    <script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>    <style>      table.controls td {        text-align: center;        padding: 2px 5px;        min-width: 60px;      }    </style>  </head>  <body>    <div id="map" class="map"></div>    <table class="controls">      <tr>        <td>hue</td>        <td><span id="hueOut"></span>°</td>        <td><input id="hue" type="range" min="-180" max="180" value="0"/></td>      </tr>      <tr>        <td>chroma</td>        <td><span id="chromaOut"></span> %</td>        <td><input id="chroma" type="range" min="0" max="100" value="100"/></td>      </tr>      <tr>        <td>lightness</td>        <td><span id="lightnessOut"></span> %</td>        <td><input id="lightness" type="range" min="0" max="100" value="100"/></td>      </tr>    </table>    <script>      /**       * Color manipulation functions below are adapted from      * https://github.com/d3/d3-color.       * 下面的颜色操作函数源自https://github.com/d3/d3-color      */      var Xn = 0.950470;      var Yn = 1;      var Zn = 1.088830;      var t0 = 4 / 29;      var t1 = 6 / 29;      var t2 = 3 * t1 * t1;      var t3 = t1 * t1 * t1;      var twoPi = 2 * Math.PI;      /**       * Convert an RGB pixel into an HCL pixel.       * 转换RGB像素为HCL像素      * @param {Array.<number>} pixel A pixel in RGB space.       * @return {Array.<number>} A pixel in HCL space.       */      function rgb2hcl(pixel) {        var red = rgb2xyz(pixel[0]);        var green = rgb2xyz(pixel[1]);        var blue = rgb2xyz(pixel[2]);        var x = xyz2lab(            (0.4124564 * red + 0.3575761 * green + 0.1804375 * blue) / Xn);        var y = xyz2lab(            (0.2126729 * red + 0.7151522 * green + 0.0721750 * blue) / Yn);        var z = xyz2lab(            (0.0193339 * red + 0.1191920 * green + 0.9503041 * blue) / Zn);        var l = 116 * y - 16;        var a = 500 * (x - y);        var b = 200 * (y - z);        var c = Math.sqrt(a * a + b * b);        var h = Math.atan2(b, a);        if (h < 0) {          h += twoPi;        }        pixel[0] = h;        pixel[1] = c;        pixel[2] = l;        return pixel;      }      /**       * Convert an HCL pixel into an RGB pixel.       * 转换HCL像素为RGB像素       * @param {Array.<number>} pixel A pixel in HCL space.       * @return {Array.<number>} A pixel in RGB space.       */      function hcl2rgb(pixel) {        var h = pixel[0];        var c = pixel[1];        var l = pixel[2];        var a = Math.cos(h) * c;        var b = Math.sin(h) * c;        var y = (l + 16) / 116;        var x = isNaN(a) ? y : y + a / 500;        var z = isNaN(b) ? y : y - b / 200;        y = Yn * lab2xyz(y);        x = Xn * lab2xyz(x);        z = Zn * lab2xyz(z);        pixel[0] = xyz2rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z);        pixel[1] = xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z);        pixel[2] = xyz2rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z);        return pixel;      }      function xyz2lab(t) {        return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;      }      function lab2xyz(t) {        return t > t1 ? t * t * t : t2 * (t - t0);      }      function rgb2xyz(x) {        return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);      }      function xyz2rgb(x) {        return 255 * (x <= 0.0031308 ?            12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);      }      var raster = new ol.source.Raster({        sources: [new ol.source.Stamen({          layer: 'watercolor'        })],        operation: function(pixels, data) {          var hcl = rgb2hcl(pixels[0]);          var h = hcl[0] + Math.PI * data.hue / 180;          if (h < 0) {            h += twoPi;          } else if (h > twoPi) {            h -= twoPi;          }          hcl[0] = h;          hcl[1] *= (data.chroma / 100);          hcl[2] *= (data.lightness / 100);          return hcl2rgb(hcl);        },        lib: {          rgb2hcl: rgb2hcl,          hcl2rgb: hcl2rgb,          rgb2xyz: rgb2xyz,          lab2xyz: lab2xyz,          xyz2lab: xyz2lab,          xyz2rgb: xyz2rgb,          Xn: Xn,          Yn: Yn,          Zn: Zn,          t0: t0,          t1: t1,          t2: t2,          t3: t3,          twoPi: twoPi        }      });      var controls = {};      raster.on('beforeoperations', function(event) {        var data = event.data;        for (var id in controls) {          data[id] = Number(controls[id].value);        }      });      var map = new ol.Map({        layers: [          new ol.layer.Image({            source: raster          })        ],        target: 'map',        view: new ol.View({          center: [0, 2500000],          zoom: 2,          maxZoom: 18        })      });      var controlIds = ['hue', 'chroma', 'lightness'];      controlIds.forEach(function(id) {        var control = document.getElementById(id);        var output = document.getElementById(id + 'Out');        control.addEventListener('input', function() {          output.innerText = control.value;          raster.changed();        });        output.innerText = control.value;        controls[id] = control;      });    </script>  </body></html>



原创粉丝点击