LINUX.ORG.RU

SVG в PNG в chrome headless

 , ,


0

1

Собственно сабж.

Интересует возможность отрисовки SVG в PNG через chrome. Нагуглил пару либ для node.js, но я в этой области 0. В какую строну копать? Может есть готовые примеры?

Мне нужно открыть SVG, отмасштабировать его, заскринить «страницу», обрезать лишнее, сохранить как PNG.

QtWebKit не предлагать - он криво рисует.

QtWebEngine не предлагать - он кривой.

UPD: SVG в PNG в chrome headless (комментарий)

★★★★★

Последнее исправление: RazrFalcon (всего исправлений: 2)

если тебе лишь конвертнуть svg то есть куча специальных конвертеров

Deleted
()
Ответ на: комментарий от Deleted

Inkscape не умеет и половину фич svg. imagemagic использует librsvg, который ещё хуже.

Я сам пишу либу для отрисовки SVG, так что знаю о чём говорю. Самый нормальный рендер - в хроме. Теперь мне нужно к нему достучатся.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Inkscape не умеет и половину фич svg.

cast AP, тут наших бьют!

Я сам пишу либу для отрисовки SVG, так что знаю о чём говорю

зачем? движок js для неё ты тоже сам пишешь?

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

тут наших бьют!

Я могу часами ныть о том, насколько ужасен Inkscape.

зачем?

Ибо нету.

движок js для неё ты тоже сам пишешь?

Как будто у inksacpe/librsvg есть js. SVG Static никто не отменял.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от Deleted

чего нет?

Нет либы для нормальной отрисовки SVG.

qtsvg

Он даже 10% стандарта не умеет.

batik

Жаба

у других то есть

Только у браузеров.

RazrFalcon ★★★★★
() автор топика

Нагуглил пару либ для node.js

всмысле для работы с headless ? Они все реализуют стандартный интерфейс для работы с websocket-api хрома через порт дебага. Например рендер PDF - это функция самого хрома,а не библиотек оберток. В общем если оно и есть, то должно быть описано тут https://chromedevtools.github.io/devtools-protocol/ Если нет, то можно как костыль делать скриншот страницы с отрендареной SVG (такое там точно есть)

Dred ★★★★★
()
Ответ на: комментарий от Dred

Я ни в js, ни в websocket не шарю. Хотелось бы готовый пример.

Вроде как скрин в png сделать можно. Затем остаётся лишь через JS получить размеры svg и обрезать уже самому.

Сама либа: https://github.com/GoogleChrome/puppeteer

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Он даже 10% стандарта не умеет.

лпп

Жаба

клиника

Только у браузеров

выше я назвал всего две библиотеки которые умеют. это не браузеры, если ты еще не понял

Deleted
()
Ответ на: комментарий от Deleted

лпп

Ну так прувца киньте. Типа поддержки mask,clipPath,filter,etc.

клиника

Ставить жабу, чтобы картинку нарисовать?

выше я назвал всего две библиотеки которые умеют.

Про batik не знаю, но inkscape, librsvg и qtsvg даже css нормально не умеют, а js не поддерживают в принципе.

RazrFalcon ★★★★★
() автор топика
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Ставить жабу, чтобы картинку нарисовать?

Одну? Если нет, то это вопрос из разряда «я у мамы фанатик». На серверах даже опенофис ставят и мсо на венду в виртуалочку, ради того чтобы документик в картиночку конвертнуть.

Deleted
()

В общем запилил такое:

'use strict';

const puppeteer = require('puppeteer');
const path = require('path');

var argv = process.argv.slice(2);
var in_path = path.resolve(argv[0]);

(async() => {

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto("file://" + in_path);

var svg_rect = await page.evaluate(() => {
    return [
        document.rootElement.x.baseVal.value,
        document.rootElement.y.baseVal.value,
        document.rootElement.width.baseVal.value,
        document.rootElement.height.baseVal.value
    ]
});

var svg_scale = 1
if (argv[2] != undefined) {
    svg_scale = argv[2] / svg_rect[2]
}

console.log(svg_rect, svg_scale)

await page.setViewport({
    width: 4000, // не пойму как сюда svg_rect пробросить, сыплет ошибки
    height: 4000,
    deviceScaleFactor: svg_scale // при этом эта переменная проходит
});

await page.screenshot({
    path: argv[1],
    clip: { x: svg_rect[0], y: svg_rect[1], width: svg_rect[2], height: svg_rect[3] }
});

browser.close();

})();

- не ясно как фон поменять на прозрачный

- не ясно что делать с растягиваемым SVG, ака <svg width="100%" height="100%">. Не знаю как получить его размеры.

cast Vit

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Дружочек, я тебе назвал уйму либ, из которых ты часть не видел, а часть из-за болезненной фиксации не и видеть не хочешь.

Когда ты сказал что делаешь свою, не зная о других, это дало достаточно информации о твоей адекватности.

Deleted
()
Ответ на: комментарий от AP

13:35, 29 October 2008‎ Jaspervdg (Talk | contribs)‎ . . (38,830 bytes) (+109)‎

На календаре 2017 год и 0.92 версия инкскейпа даже в дебиане

ps. не, я понимаю, что анимации там скорее всего не работают, но фильтры и т.п. заметно улучшились, за десяток то лет

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

либы унылые

ты болен, либы либо выполняют свою функцию, либо нет. тебе же надо чтобы они тебя веселили

Deleted
()
Ответ на: комментарий от Deleted

Когда ты сказал что делаешь свою, не зная о других

Оставьте свои больные фантазии при себе.

Пруфца вам: https://itmages.ru/image/view/6066116/7a8190e6

resvg - это моя либа.

А теперь продолжайте втирать про хорошую поддержку у существующих либ.

RazrFalcon ★★★★★
() автор топика

SVG в PNG через chrome

Да вы, батенька, поехали совсем.

Это же ведь оверкилл невероятный, тащить целый браузерный движок ради конвертации. Разве нет?

Deleted
()
Ответ на: комментарий от Deleted

Анимации у инкскейпа за это время не прибавилось.

Ну и тащемта бери тест свит и попробуй наново.

AP ★★★★★
()
Ответ на: комментарий от Deleted

Мне локально он нужен, для тестов. Тем более я и так сейчас QtWebKit использую...

Ну и в век электрона такое говорить...

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от AP

Там всё очень плохо. Я проверяю регулярно.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Так в век электрона никто и не говорит. Он настанет не раньше четвертого тысячелетия, если вообще настанет.

Deleted
()
Ответ на: комментарий от Deleted

Уже настал. Выходите из анабиоза.

RazrFalcon ★★★★★
() автор топика

Очень примитивное решение. Но для моих задача достаточно:

'use strict';

const puppeteer = require('puppeteer');
const path = require('path');

var argv = process.argv.slice(2);
var svg_path = path.resolve(argv[0]);
var png_path = argv[1];

(async() => {

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto("file://" + svg_path);

var svg_file_size = await page.evaluate(() => {
    var svg = document.getElementsByTagName("svg")[0];
    return [
        svg.getAttribute("width"),
        svg.getAttribute("height")
    ]
});

var is_dynamic = svg_file_size[0] == "100%" && svg_file_size[1] == "100%"

if (is_dynamic) {
    var svg_width = 0;
    if (argv[2] == undefined) {
        console.log("Error: width argument must be set")
        process.exit()
    } else {
        svg_width = parseInt(argv[2])
    }

    await page.setViewport({
        width: svg_width,
        height: svg_width
    });

    var svg_view_box = await page.evaluate(() => {
        var svg = document.querySelector('svg')
        var box = svg.getAttribute('viewBox');
        return box.split(/\s+|,/)
    });

    const scale = svg_width / svg_view_box[2]

    const h = svg_view_box[3] * scale
    const y = (svg_width - h) / 2

    await page.screenshot({
        path: png_path,
        clip: { x: 0, y: y, width: svg_width, height: h }
    });
} else {
    var svg_rect = await page.evaluate(() => {
        var root = document.rootElement;
        return [
            root.x.baseVal.value,
            root.y.baseVal.value,
            root.width.baseVal.value,
            root.height.baseVal.value
        ]
    });

    var svg_scale = 1
    if (argv[2] != undefined) {
        svg_scale = argv[2] / svg_rect[2]
    }

    await page.setViewport({
        width: 2000,
        height: 2000,
        deviceScaleFactor: svg_scale
    });

    await page.screenshot({
        path: png_path,
        clip: { x: svg_rect[0], y: svg_rect[1], width: svg_rect[2], height: svg_rect[3] }
    });
}

browser.close();

})();

RazrFalcon ★★★★★
() автор топика
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от annulen

У него поддержка SVG плохая. У chromium намного лучше. ХЗ в чём причина.

Проявляется только на хитрых SVG.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от annulen

Например: https://github.com/KDE/oxygen-icons/blob/master/scalable/actions/small/16x16/...

Я могу кучу примеров перевести.

При этом QtWebKit из поставки Qt - вообще дно. Ваш форк, если не ошибаюсь, 5-й билд, намного лучше. Но до хрома далеко.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Так в чем ведь засада: некоторые несознательные граждане знают, что есть баги, но почему-то молчат в тряпочку...

annulen ★★★★★
()
Ответ на: комментарий от RazrFalcon

Кстати в «дне» этот файл рендерится нормально, и я даже догадываюсь почему, есть один «нехороший» патч который в других ситуациях вызывает крэш...

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от annulen

Ну тут всё сложно.

Во-первых, составлять баги - сложно. Это время/работа.

Во-вторых, мне казалось, что у хрома и qtwebkit общая кодовая база. Куда посылать багрепорты - хз. Вам или в багтрекер самого вебкита.

Ну и для примера - я отправил с пятёрку багов в Inkscape. Все открыты уже по паре лет. Ака - толку 0.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от annulen

Падения вебкита я тоже ловил. Тем более непредсказуемые. Один раз норм, один раз падало.

Мне нужна реализация, которая лучше всего работает. Сейчас это headless chrome через ноду. Время рендера унылое, но лучше ничего нету.

Зачем мне посылать багрепорты в другие проекты, если есть тот, который работает...

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Во-вторых, мне казалось, что у хрома и qtwebkit общая кодовая база

Можно открыть тот же файл в WebKitGTK - я открыл и увидел, что баг специфичен для Qt (иначе бы его давно поправили, так как проблема серьезная).

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

Кстати хром использует по сути ту же самую кодовую базу SVG, за четыре года конечно могли возникнуть расхождения, но вряд ли сильные

annulen ★★★★★
()
Ответ на: комментарий от RazrFalcon

Да я уже понял, что это за баг, и надо сначала его исправить, так как он может по-разному проявляться

annulen ★★★★★
()
Ответ на: комментарий от RazrFalcon

Хотя если есть артефакты и при этом в онсоли нет сообщений от QPainter, то кидай

annulen ★★★★★
()
6 января 2018 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.