Я использую следующую функцию для преобразования SVG в PNG и предлагаю его для загрузки:

<svg id="chart">
    ...some contenthere
</svg>

function() {
        var svg = $("#chart")[0],
            bBox = $('#chart')[0].getBBox();

        var width = bBox.width*2,
            height = bBox.height*2;

        var canvas = $("canvas")[0],
            serializer = new XMLSerializer(),
            svgString = serializer.serializeToString(svg);

        canvas.width = width;
        canvas.height = height;

        canvg(canvas, svgString);

        var dataURL = canvas.toDataURL('image/png'),
            data = atob(dataURL.substring('data:image/png;base64,'.length));

        asArray = new Uint8Array(data.length);

        for (var i = 0; i < data.length; ++i) {
            asArray[i] = data.charCodeAt(i); 
            } 

        var blob = new Blob([asArray.buffer], {type: 'image/png'}); 
        saveAs(blob, 'climatechart.png'); 
}

На самом деле он работает нормально, несмотря на то, что выходное изображение имеет тот же размер, что и SVG в браузере. Как я могу установить новый размер изображения? Я также пытался получить размер непосредственно из SVG, а не BBox, но это было то же самое.

0
flixe 16 Дек 2015 в 16:12

4 ответа

Лучший ответ

Хорошо, спасибо за предложения, я наконец нашел решение, которое идеально подходит (согласно подсказке Седрика Хартлендса). Атрибут viewbox был частью, которая полностью отсутствовала в моем коде. viewbox определяется следующим образом:

viewbox = "x y width height"

Таким образом, чтобы увеличить <svg> и ВСЕ элементы в нем, необходимо убедиться, что width и height окна просмотра точно соответствуют новой ширине и высоте {{X3 }} element:

//original version
<svg> width="100" height="100" viewbox="0 0 100 100" preserveAspectRatio="xMinYMin meet"</svg>

//scaled up version
<svg> width="200" height="200" viewbox="0 0 200 200" preserveAspectRatio="xMinYMin meet"</svg>

Если я преобразую увеличенный svg в canvas, он уместится на все изображение без потери качества (в любом случае это самое большое преимущество векторной графики). Не могу поверить, что мне понадобилось так много времени, чтобы получить это.

0
flixe 17 Дек 2015 в 10:21

Размеры документов SVG можно изменить с помощью атрибутов высоты и ширины, если элемент svg определяет атрибут viewBox в зависимости от его размера; например

<svg width="500" height="200" viewBox="0 0 50 20" >

Как только viewBox был установлен, масштабирование svg в canvas работает так, как вы кодировали.

0
Cédric Hartland 17 Дек 2015 в 09:18

Вы можете легко изменить размер холста, как вы можете нарисовать его как холст. В следующем примере игнорируется любой рендеринг SVG, который работает в соответствии с вашим вопросом, но он показывает, как вы можете легко изменить размер холста, используя другой холст:

var myCanvas = document.createElement('canvas');
var myCtx    = myCanvas.getContext('2d');
    myCanvas.width = 200;
    myCanvas.height = 200;
    myCtx.arc(100, 100, 100, 0, Math.PI * 2, true);
    myCtx.fill();

var seCanvas = document.createElement('canvas');
var seCtx    = seCanvas.getContext('2d');
    seCanvas.width = 200;
    seCanvas.height = 200;
    seCtx.drawImage(myCanvas, 0, 0, 100, 100);

document.body.appendChild(myCanvas);
document.body.appendChild(seCanvas);

После этого вы можете просто продолжить процесс, используя этот новый холст.

0
somethinghere 16 Дек 2015 в 13:50

Это решение основано на удаленном сервере форматирования, а не на локальном коде. Он использует серверную часть XSL FO для прямой визуализации SVG в растровое изображение, что позволяет вам устанавливать разрешение для высококачественного вывода.

Документация: http://www.cloudformatter.com/CSS2Pdf.APIDoc.Usage

Пример: http://jsfiddle.net/g75t4oyq/

Реализация кода для формата JPG @ 300dpi из SVG в div:

click="return xepOnline.Formatter.Format('JSFiddle', {render:'newwin', mimeType:'image/jpg', resolution:'300', srctype:'svg'})";
jQuery('#buttons').append('<button onclick="'+ click +'">JPG @300dpi</button>');
1
A J 9 14 Окт 2016 в 10:07