티스토리 뷰

대부분에 브라우저에서는 CSS Filter를 적용해서 grayscale 처리가 가능하지만 IE 10 이상에서는 지원하지 않는다.
그래서 SVG feColorMatrix Filter 활용해서 처리 하였다.

CSS Filter 방법


.grayscale {
  /* Firefox 10+, Firefox on Android */
  filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='grayscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0'/></filter></svg>#grayscale");
  /* IE 6-9 */
  filter: gray;
  /* Chrome 19+,  Safari 6+, Safari 6+ iOS, Opera 15+ */
  -webkit-filter: grayscale(100%);
}

SVG Filter 방법

  • imageconverter.js

var namespace = "http://www.w3.org/2000/svg";

function svg(tag, attribs) {
  var e = document.createElementNS(namespace, tag);
  if (typeof attribs == 'object') {
    var k, v;
    for (k in attribs) {
      v = attribs[k];
      e.setAttribute(k, v);
    }
  }
  return e;
}

const grayscale = (src, callback, options = {}) => {
  var root = svg("svg", {width: options.width || "0", height: options.height || "0"});
  var defs = svg("defs");
  root.appendChild(defs);
  var filterId = "F" + Math.random().toString(36).substring(7);
  var filter = svg("filter", {id: filterId});
  defs.appendChild(filter);
  var colorMatrix = svg("feColorMatrix", {type: "saturate", values: "0.001"});
  filter.appendChild(colorMatrix);
  var img = new window.Image();
  img.onload = function() {
      var w = img.width;
      var h = img.height;
      root.setAttribute("width", w);
      root.setAttribute("height", h);
      root.setAttribute("viewBox", "0 0 " + w + " " + h);
      var image = svg(
          "image", 
          {
              x: 0, y: 0,
              width: w, height: h,
              filter: "url(#" + filterId + ")"
          }
      );

      // image.setAttributeNS("http://www.w3.org/1999/xlink", "href", src);
      image.setAttribute("xlink:href", src);
      root.appendChild(image);

      var svgString = new XMLSerializer().serializeToString(root);
      svgString = svgString.replace(/"/g,'');
      svgString = svgString.replace(/xmlns:NS1=""/g,'');
      svgString = svgString.replace(/NS1:/g,'');

      callback(svgString)
  };
  img.onerror = function(err) {
      console.info("[index] err=...", err);
  };
  img.src = src;
}

export default grayscale;
  • detail.vue

<template>
    ...
  <div v-html="grayScaleImage" />
      ...
</template>
<script>
import grayscale from '@/utils/imageconverter.js'
export default {
  data: () => ({
    image: 'http://192.168.0.7:8000/1575190630264.jpg',
    grayScaleImage: null
  }),
  mounted () {
    grayscale(this.image, (svgString) => {
      this.grayScaleImage = svgString
    })
  },
}
</script>

Image class 를 활용한 비동기 처리이기 때문에 callback 함수를 정의해 줘야한다

http://jsfiddle.net/azx3mxmt/3/
https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2025/05   »
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
글 보관함