LINUX.ORG.RU

Похоже баг с командой --query-all

 ,


0

1

Я расположил в SVG некоторые графические образцы. Нужно было каждый образец растеризвать отдельно из этого SVG для дальнейших исследований. Так как образцов много я использовал для этой задачи процесс Inkscape в shell режиме. Я парсил SVG находил объект, программно создавал новый svg с этим объектом и необходимым окружением, и этот svg растеризовывал.

Можно было это сделать с помощью команды --export-area-drawing, но нужен был ещё кусок окружения. Но чтобы обойти баг, который хочу здесь описать, я именно так и сделал, а потом добавлял к растровому рисунку окружение с помощью ImageMagick.

Однако у Inkscape есть команда --export-area, с помощью которой можно было обойтись без ImageMagick. Я пытался растеризацией выцепить объект с помощью данных Inkscape процесса, получаемых используя команду --query-all. Однако было не понятно, что за значения «y» выводила команда для использования в параметрах --export-area-drawing, хотя с параметром «x» всё было понятно. После многочисленных опытов я понял что в качестве значения параметра «y» выводится хрен знает что. Линейной связи с его значением и необходимым мне параметром не было!

Inkscape 0.91 r13725

Это действительно баг или я чего-то не понял?

★★★★★

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

На словах как-то туманно всё.

Я так понял, ты экспортируешь объект с полями вокруг него? То есть просто --export-id тебе не подходит?

Это действительно баг или я чего-то не понял?

Похоже на баг, но он, вероятно, связан с внутренним устройством координат в Инкскейпе. Дело в том, что в гуе координаты считаются от левого-нижнего края «листа», увеличиваясь вверх и такие же принимаются для аргумента --export-area, но --query-all выдаёт координаты, посчитанные от левого-верхнего края «листа» с увеличением значений вниз. В самом SVG координаты объектов записаны как в --query-all с учётом некоторых трансформаций. С этой стороны, вроде как бы и не баг.

Косяк в том, что через командную строку мы не можем узнать размеры листа для того, чтобы вычислить гуишную координату для экспорта, вычтя вывод --query-all из высоты листа. Может как-то можно узнать размеры листа из интерактивного шелла (--shell)? Я не знаю.

Накидал поясняющую схемку :)

Кстати, для некоторых форматов можно указать поля:

--export-margin=VALUE      Only for PS/EPS/PDF, sets margin in mm around exported area (default 0)

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

Это-то понятно, но тогда зависимость между получаемым --query-all параметром и нужного мне параметра для --export-area должна быть линейной с коэффициентом пропорциональности -1.

Но как показывает опыт она вообще не линейная.

Вот результаты моих опытов:

# -1282.3207 2182                                                                                                              
# -1296.7252 2182                                                                                                              
# -1298.7455 2182                                                                                                              
# -1240.2524 2048

левая колонка полученный параметр от --query-all, вторая - необходимый мне параметр для --export-area. Всегда прижимал объект к нижнему краю картинки.

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

А высота листа какая?

Ещё может быть, что твой SVG сделан не в Инкскейпе и viewBox отличается от инкскейповского. А ещё могут быть для <g> объектов назначены трансформации и тогда их, возожно, надо вычислять, но, вроде, Инкскейп сам всё правильно вычисляет.

А можешь свою SVG куда-нибудь скинуть?

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

Провёл я тут эксперимент по-серьёзнее. Зависимость оказалась линейной с k=-1 на этот раз. Или баг не показал себя или я в прошлом эксперименте где-то накосячил.

Вот код:

http://pastebin.com/nrp3p1SC

http://pastebin.com/8fbpK5LU

Я определил закон и если раскомментировать строку 132:

    # real_y = 886.154 - y

то растеризация будет происходить по нему.

Остаётся понять откуда получать число 886.154. Также по картинкам видна невысокая точность закона, что для моих задач не принципиально.

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

твой SVG сделан не в Инкскейпе

Нет. Я группирую растровые изображения в svg, снабжая их некоторыми векторными элементами и метаданными (именами). Парся svg с ними легко можно работать программно по отдельности, а к результатам расчётов я прикладываю экспортированную из svg pdf-ку. Все необходимые функции покрываются inkscape.

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

Знакомый кодец ;)

Я не стал проверять все варианты, но первый попавшийся текст корректно экспортировался по моей методике. Версия Инкскейпа у меня точно та же, что и у тебя. Дистр — Арч.

Последовательность моих действий:

$ grep viewBox ink_bug.svg
   viewBox="0 0 1986.265 2172.5702"

$ inkscape --query-all ink_bug.svg | grep text4154
text4154,26.677734,215.15045,178.67193,26.803493

$ python
>>> 2172.5702 - 215.15045
1957.41975
>>> 1957.41975 - 26.803493
1930.616257
>>> 26.677734 + 178.67193
205.349664
^D

$ inkscape -e test.png -a 26.677734:1957.41975:205.349664:1930.616257 ink_bug.svg

Результат.

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

Проверил все:

$ inkscape --query-all ink_bug.svg | \
  awk -F, '{ ph=2172.5702; system("inkscape -e exp/"$1".png -a "$2":"ph-$3":"$2+$4":"ph-$3-$5" ink_bug.svg") }'

Всё корректно экспортировалось в предварительно созданную папочку exp.

$ inkscape --version
Inkscape 0.91 r13725 (May  3 2016)
anonymous
()
Ответ на: комментарий от anonymous

Действительно всё просто и работает. Нужно было просто копировать viewBox в svg для каждого объекта, а не брать от балды.

Странно, конечно, что координатные системы не совпадают.

Благодарю за помощь.

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

Нужно было просто копировать viewBox

Я, если честно, так и не разобрался, что ты там делаешь :) Если ты копируешь куски XML, то, видимо, надо учитывать все трансформации вверх по иерархии. Вообще, не знаю. А может надо просто разницу высоты страниц только учитывать.

Странно, конечно, что координатные системы не совпадают.

Да уж, это было чьё-то очень «мудрое» решение пойти вразрез стандарту и общепринятой в CG координатной системе. Теперь мучаются все. И пользователи и девелоперы.Реквест на исправление висит с 2003 года и было несколько попыток исправить эту оплошность, но, видимо, это нереально сделать.

Товарищ там пишет, что основная проблема в том, что математика, разбросанная по всему коду, использует инвертированные координаты.

Вот тут даже пытались денежки собрать на исправление.

Благодарю за помощь.

Пожалуйста ;)

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

Если ты копируешь куски XML, то, видимо, надо учитывать все трансформации вверх по иерархии.

Моя задача позволяет делать так, чтобы никаких иерархий трансформаций не было.

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

Если ты копируешь куски XML, то, видимо, надо учитывать все трансформации вверх по иерархии.

Да я так и делаю. Копирую куски и трансформации не учитываю. Стараюсь чтобы на рисунках их не было.

Но вот только сейчас заметил что inkscape почти всегда вставляет трансформацию слоя (старшего тега g). Даже в приложенном файле такая трансформация есть.

Но тем не менее без её учёта всё работает. Вот код:

http://pastebin.com/dSAVcrVZ

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

Ага, понятно. Если что, то, думаю, можно эту трансформацию тоже копировать.

Кстати, ты можешь подсократить код SVG-шаблона в generate_svg():

def generate_svg (filename, node, viewbox, transform):
    svg = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="%s">
        <g transform="%s">%s</g></svg>'''

    with open(filename, 'w') as f:
        f.write(svg % (viewbox, transform, node.toxml()))

То есть, даже объявление <?xml...?> можно не писать. И это легально.

А тебе точно нужен временный SVG-файл? Может проще сразу из оригинала растр экспортировать, с опцией --export-id-only?

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