Как добавить четкости, полученным SVG-фильтрами, контурам. Не добавляется contrast(200%) после SVG-фильтров

Пробую получить контуры изображений с помощью серии фильтров SVG. На сниппете можно переключать изображения и включать/выключать наложение фильтра.

let img_sources = [
    "https://image.freepik.com/free-vector/flat-car-poster-with-photo-horizontal_52683-64510.jpg",
    "https://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg?v=47faa659a05e",
    "https://image.freepik.com/free-vector/enjoy-summer-3d-realistic-background-with-clouds-daisies-grass-leaves-product-podium_87521-3206.jpg",
    "https://image.freepik.com/free-vector/linear-flat-wedding-monograms_52683-64319.jpg",
    "https://image.freepik.com/free-vector/gradient-grainy-gradient-shapes_23-2148975080.jpg",
    "https://image.freepik.com/free-photo/metallic-gold-green-leaves-textured-background_53876-101336.jpg",
    "https://image.freepik.com/free-psd/friends-representing-inclusion-concept-with-mock-up-t-shirts_23-2148997994.jpg",
    "https://image.freepik.com/free-psd/3d-space-rocket-with-smoke_23-2148938939.jpg"
];

let image = document.querySelector('image');
let container = document.getElementById('inputContainer');

let input_range = document.createElement('input');
let range_label = document.createElement('label');
range_label.textContent = 'ИЗОБРАЖЕНИЯ';
range_label.style.marginRight = '20px';
input_range.type = 'range';
input_range.min = 0;
input_range.max = img_sources.length - 1;
input_range.value = 0;
input_range.addEventListener('change', e => {
    draw(e.target.value);
})
container.append(input_range);
container.append(range_label);

draw();

let input_checkbox = document.createElement('input');
let checkbox_label = document.createElement('label');
input_checkbox.checked = true;
checkbox_label.textContent = 'ФИЛЬТР';
input_checkbox.type = 'checkbox';
input_checkbox.addEventListener('change', e => {
    image.setAttribute('style', e.target.checked ? "filter: url(#filter)" : "");
});
container.append(input_checkbox);
container.append(checkbox_label);

function draw(val=0){
    image.setAttribute('href', img_sources[val]);
}
<svg viewbox="0 0 400 200">
    <filter id="filter" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="linearRGB">
        <feMorphology operator="dilate" radius="0.5 0.5" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" result="morphology"/>
        <feBlend mode="difference" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" in2="morphology" result="blend"/>
        <feColorMatrix type="luminanceToAlpha" x="0%" y="0%" width="100%" height="100%" in="blend" result="colormatrix3"/>
    </filter>
    <image id="filtered" href="" height="200" width="200" style="filter: url(#filter)"/>
</svg>
<div id="inputContainer" style="position: fixed; top: 4px; left: 4px"></div>

Но после получения контуров разной степени интенсивности не могу получить равномерность "темности" контура или проявить его с помощью увеличения контрастности. Пробовал добавить contrast(200%) в цепочку фильтров, но он совершенно не оказывает никакого действия.

В идеале после повышения контрастности, положить полученное изображение на черный фон и маской или другим инструментом извлечь четкие черные линии. Как можно это сделать?


Ответы (1 шт):

Автор решения: UModeL

Если CSS-фильтр не имеет видимого эффекта, то почему бы не воспользоваться <feBlend mode="multiply">?

let img_sources = [
    "https://image.freepik.com/free-vector/flat-car-poster-with-photo-horizontal_52683-64510.jpg",
    "https://image.freepik.com/free-vector/enjoy-summer-3d-realistic-background-with-clouds-daisies-grass-leaves-product-podium_87521-3206.jpg",
    "https://image.freepik.com/free-vector/linear-flat-wedding-monograms_52683-64319.jpg",
    "https://image.freepik.com/free-vector/gradient-grainy-gradient-shapes_23-2148975080.jpg",
    "https://image.freepik.com/free-vector/gradient-grainy-gradient-texture_23-2148974472.jpg",
    "https://image.freepik.com/free-vector/gradient-grainy-gradient-shape-set_23-2148971570.jpg",
    "https://image.freepik.com/free-psd/3d-space-rocket-with-smoke_23-2148938939.jpg"
];

let image = document.querySelector('image');
let container = document.getElementById('inputContainer');

let input_range = document.createElement('input');
let range_label = document.createElement('label');
range_label.textContent = 'ИЗОБРАЖЕНИЯ';
range_label.style.marginRight = '20px';
input_range.type = 'range';
input_range.min = 0;
input_range.max = img_sources.length - 1;
input_range.value = 0;
input_range.addEventListener('change', e => {
    draw(e.target.value);
})
container.append(input_range);
container.append(range_label);

draw();

let input_checkbox = document.createElement('input');
let checkbox_label = document.createElement('label');
input_checkbox.checked = true;
checkbox_label.textContent = 'ФИЛЬТР';
input_checkbox.type = 'checkbox';
input_checkbox.addEventListener('change', e => {
    image.setAttribute('style', e.target.checked ? "filter: url(#filter)" : "");
});
container.append(input_checkbox);
container.append(checkbox_label);

function draw(val=0){
    image.setAttribute('href', img_sources[val]);
}
<svg viewbox="0 0 400 200">
    <filter id="filter" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="linearRGB">
        <feMorphology operator="dilate" radius="0.5 0.5" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" result="morphology"/>
        <feBlend mode="difference" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" in2="morphology" result="blend"/>
        <feColorMatrix type="luminanceToAlpha" x="0%" y="0%" width="100%" height="100%" in="blend" result="colormatrix3"/>
        
        <feBlend mode="multiply" in="colormatrix3" result="multi1"/>
        <feBlend mode="multiply" in="multi1" result="multi2"/>
        <feBlend mode="multiply" in="multi2" result="multi3"/>
        <feBlend mode="multiply" in="multi3" result="multi4"/>
    </filter>
    <image id="filtered" href="" height="200" width="200" style="filter: url(#filter)"/>
</svg>
<div id="inputContainer" style="position: fixed; top: 4px; left: 4px"></div>

→ Ссылка