Преобразование изображения с примененным фильтром SVG в двоичный файл или base64 для сохранения в бэкэнде

Я показываю изображение в графическом интерфейсе и применяю к нему фильтры SVG. Теперь мое требование состоит в том, чтобы сохранить это измененное изображение [с примененным фильтром SVG] путем преобразования в двоичный файл или base64. Я попытался конвертировать с помощью canvas. Но не смог этого добиться. Вот что я пробовал до сих пор. Может ли кто-нибудь дать несколько советов, чтобы продолжить.

Ссылка JsFiddle

<div class="item active filtered" data-slide-number="0">
    <svg style="overflow: hidden; height: 637px; width: 546px;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events">
        <defs>
            <filter id="svgBlur" width="110%" height="110%">
                <feComponentTransfer id="bFilter">
                    <feFuncR id="brightness1" class="brgt" type="linear" slope="2"></feFuncR>
                    <feFuncG id="brightness2" class="brgt" type="linear" slope="1"></feFuncG>
                    <feFuncB id="brightness3" class="brgt" type="linear" slope="1"></feFuncB>
                </feComponentTransfer>
                <feComponentTransfer id="cFilter">
                    <feFuncR id="contrast1" class="cnst" type="linear" slope="1" intercept="-0.01"></feFuncR>
                    <feFuncG id="contrast2" class="cnst" type="linear" slope="1" intercept="-0.01"></feFuncG>
                    <feFuncB id="contrast3" class="cnst" type="linear" slope="1" intercept="-0.01"></feFuncB>
                </feComponentTransfer>
                <feComponentTransfer id="gFilter">
                    <feFuncR id="gamma1" class="gama" type="gamma" amplitude="1" exponent="1" offset="0"></feFuncR>
                    <feFuncG id="gamma2" class="gama" type="gamma" amplitude="1" exponent="1" offset="0"></feFuncG>
                    <feFuncB id="gamma3" class="gama" type="gamma" amplitude="1" exponent="1" offset="0"></feFuncB>
                </feComponentTransfer>
                <feColorMatrix id="saturation" type="saturate" values="1"></feColorMatrix>
            </filter>
        </defs>
        <g id="viewport-20160404045307934" class="svg-pan-zoom_viewport" transform="matrix(1.011111111111111,0,0,1.011111111111111,2.52222222222224,0)">
            <image xlink:href="https://www.ricoh.com/r_dc/caplio/r7/img/sample_03.jpg" class="img-responsive" width="90%" id="imageStyling" height="630px" style="height: 630px; width: 536px;" filter="url(#svgBlur)" name="ipsDF14-2-29Feb16-9d80-1a94a2e8c121"></image>
        </g>
    </svg>
</div>

    <button id="save">Save</button>

    <canvas id="canvas"></canvas>



$(document).ready(function() {
    var btn = document.querySelector('button');
    var svg = document.querySelector('svg');
    var canvas = document.querySelector('canvas');
    $("#save").click(function() {

        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        var data = (new XMLSerializer()).serializeToString(svg);
        var DOMURL = window.URL || window.webkitURL || window;

        var img = new Image();
        var svgBlob = new Blob([data], {
            type: 'image/svg+xml;charset=utf-8'
        });
        var url = DOMURL.createObjectURL(svgBlob);
        alert(JSON.stringify(url));
    })
});

person Nofi    schedule 04.04.2016    source источник


Ответы (1)


Из-за соображений безопасности вы не сможете конвертировать SVG в изображение во многих случаях, особенно если SVG указывает на внешние источники. Некоторые браузеры принимают встроенные ресурсы, такие как изображения и CSS, но даже после этого некоторые браузеры, такие как IE, этого не допустят.

Вариант 2 — нарисовать изображение на холсте и использовать новый " свойство filter" контекста. В настоящее время его поддерживает только Firefox, но только если вы включите его с помощью флагов (canvas.filters.enabled). Другие поставщики довольно прохладно относятся к этой идее, поэтому их поддержка ограничена. Однако, если это частный проект, то это может быть достаточно хорошим решением; фильтры позволяют применять фильтры непосредственно к растровому изображению, минуя SVG, используя те же определения. Если это публичный проект, у вас остается вариант 3 ниже -

Вариант 3 — реализовать алгоритмы фильтрации в коде и применить их к холсту. Это немного больше работы (на самом деле немного больше), но эй, мы разработчики, и программирование — это весело!! :)

Вы можете найти основу и формулы для фильтров в спецификациях SVG, а также в других местах. .

Или проверьте некоторые библиотеки, которые уже прошли проверку.

person Community    schedule 04.04.2016
comment
Большое спасибо за ваш подробный пост. Собираюсь выбрать вариант 3. Удачного кодирования :) - person Nofi; 04.04.2016
comment
Для варианта 1 я написал этот скрипт, который будет обрабатывать большинство доступных внешних ресурсов и реализовывать их обратно в svg. до того, как он будет нарисован на холсте. Тем не менее, ограничения IE‹Edge действуют, но для этих браузеров возможен простой щелчок правой кнопкой мыши на svg + save as... *.png. Что касается варианта 2, браузеры webkit действительно реализовали некоторые (по крайней мере, blur(), saturate(), url()! ) и под флагом Experimental canvas features, yeeha ГП-ускоренная фильтрация в реальном времени на холсте грядет! К сожалению, вариант 3 пока единственный кроссбраузерный. - person Kaiido; 04.04.2016