티스토리 뷰
대부분에 브라우저에서는 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