SVG: проблема с отрисовкой [Графика, форматы]

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

SVG: проблема с отрисовкой [Графика, форматы]

Сообщение Moneo » 27.05.2017 02:54:19

Добрый день. Возникла необходимость скачивания svg с сайта, изменения размера под фиксированную ширину и отрисовка картинки в ячейке StringGrid (использование в качестве иконок). Подойте вариант конвертации в png или jpg.
Набросал код для проверки, но он не отображает сложный тестовый svg файл, только примитивные. Прикрепил два тестовых svg, один из них работает, второй нет. Прошу вашей помощи и советов по решению задачи.
Код: Выделить всё
fpvectorialpkg, fpvectorial,fpvtocanvas
...

var
VECDoc:TvVectorialDocument;
VEC:TvVectorialPage;
begin
paintbox1.Canvas.Clear;
VECDoc:=TvVectorialDocument.create;
try

vecdoc.ReadFromFile('6226.svg');

DrawFPVectorialtoCAnvas(VecDoc.GetPageAsVectorial(0),Paintbox1.canvas,0,Paintbox1.height-100,1,-1);
finally
VecDoc.free;
end;
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось Moneo 27.05.2017 15:57:47, всего редактировалось 3 раз(а).
Moneo
новенький
 
Сообщения: 21
Зарегистрирован: 21.03.2017 17:04:01

Re: SVG: проблема с отрисовкой

Сообщение vitaly_l » 27.05.2017 10:20:11

Moneo писал(а):не отображает сложный тестовый svg файл

Откройте svg в текстовом файле. Увидите xml. При желании сможете сделать свой компонент и рисовать на канвасе все линии и прочие простые фигуры. Там нужно написать примерно 10-ть или 12-ть обработчиков, каждого типа.

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

Смотрите код fpvectorial, fpvtocanvas + откройте файл svg в текстовом редакторе и вычислите, каких именно обработчиков из вашего рисунка нет в fpvectorial,fpvtocanvas, при отрисовке сложной фигуры льва. Соответственно, затем допишите обработку фигур типа: path - для этих модулей и будет рисовать. Там сложного ничего нет, path - это массив точек, который закрашивается, для этого есть стандартная функция канваса. Можете прямо из файла брать массив и самостоятельно рисовать этот массив на любом канвасе. Либо, если path есть, то возможно имеет смысл, убрать в файле со львом - все группировки объектов.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SVG: проблема с отрисовкой

Сообщение Moneo » 27.05.2017 11:37:26

Спасибо vitaly_l, теперь становится понятно что актуальных рисовальщиков нету и надо писать своё, но есть пару вопросов:

1. Строчка с областью рисования влияет на рисование с fpvectorial или только в браузере, если влияет, то как этими координатами пользоваться.
Код: Выделить всё
viewBox="-177.6 335.9 102.2 230" style="enable-background:new -88.6 167.9 51.2 8;"


2. Помимо определяющего атрибута d и координат path содержит много других определяющих букв - для этого я так понял надо читать английскую спецификацию svg и path в частности?

4. И самый беспокоящий меня вопрос как выполнить изменение размера исходного svg:

1) делить все координаты сразу на число во сколько раз мне нужно меньше получить изображение?
2) как вычислить тогда что на всех отрисованных объектах в конце рисования у меня получилась фиксированная ширина в 32 пиксела?
3) Есть еще один вариант с измененением размера уже после отрисовки, только какой командой не знаю.
Moneo
новенький
 
Сообщения: 21
Зарегистрирован: 21.03.2017 17:04:01

Re: SVG: проблема с отрисовкой

Сообщение Снег Север » 27.05.2017 11:51:54

Для сложных случаев попробуйте для конвертации Inkscape - есть возможность запускать конвертацию командной строкой, описано тут:
https://mijingo.com/blog/exporting-svg- ... h-inkscape
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: SVG: проблема с отрисовкой

Сообщение vitaly_l » 27.05.2017 11:58:10

Moneo писал(а):становится понятно что актуальных рисовальщиков нету

не факт. возможно кто-то уже сделал (подождите народ подтянется подскажут).
Moneo писал(а):как этими координатами пользоваться

их всегда две: Х и У - соответственно строку нужно отпарсить в с условием что каждая первая в паре это Х, а вторая У. затем передать эти координаты канвасу. Там посмотрите - у канваса, есть свой формат скармливания ему Х и У массивов.
Moneo писал(а):Помимо определяющего атрибута d и координат path содержит много других определяющих букв - для этого я так понял надо читать английскую спецификацию svg и path в частности?

можно додумать. там всё должно быть предельно просто. единственная сложность когда path с пустыми областями внутри.
Moneo писал(а):И самый беспокоящий меня вопрос как выполнить изменение размера исходного svg:

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

:arrow: Inkscape - должен уметь читать path.

/
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SVG: проблема с отрисовкой

Сообщение zub » 27.05.2017 12:22:12

vitaly_l
>>Там сложного ничего нет
))
>>единственно верное решение. разделить на нужную величину все цифры
единственно верное - умножить все координаты на соответствующую матрицу))
Moneo
На данном этапе развития fpvectorial ниче серьезного из себя не представляет. Заявлена куча форматов, но ничто (из того что нужно мне) толком не поддерживается.
Посмотрите https://sourceforge.net/p/lazarus-ccr/s ... fpvviewer/ там есть вариант рендера используя сторонний конвертер rsvg - имхо лучший вариант что можно получить в лазаре. написание своего рендера нерассматриваю изза сложности.

Добавлено спустя 1 час 48 минут 40 секунд:
еще есть aggpas он тоже вроде умеет svg, но не проверял
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: SVG: проблема с отрисовкой

Сообщение Moneo » 27.05.2017 15:11:06

Снег Север писал(а):Для сложных случаев попробуйте для конвертации Inkscape

Читал уже про Inkscape, но это внешняя конвертация, а для решения задачи нужна либо внутренняя отрисовка в ячейки либо внутренняя конвертация и resize на лету из самой программы. Как временный затык пока не найдено решение сделал скриптовую конвертацию через photoshop и light resizer, но как решение данный метод не подходит.

vitaly_l писал(а):их всегда две: Х и У - соответственно строку нужно отпарсить в с условием что каждая первая в паре это Х, а вторая У. затем передать эти координаты канвасу.

Про координаты я знаю что их две, я спросил про влияние области отображения svg файла viewbox на canvas в программе..нужно ли подставлять туда именно эти координаты из viewbox и тут их 4 (координат), а в канвасе всего 2 x и y, первые я так понял не координаты, а отступы от угла..только какого (вроде не левого верхнего)?

vitaly_l писал(а):единственная сложность когда path с пустыми областями внутри.

Что вы имеете ввиду под пустыми областями..чуть подробнее можно?

zub писал(а):единственно верное решение. разделить на нужную величину все цифры
единственно верное - умножить все координаты на соответствующую матрицу))

Почему умножать, а не делить?

zub писал(а):Посмотрите https://sourceforge.net/p/lazarus-ccr/s ... fpvviewer/ там есть вариант рендера используя сторонний конвертер rsvg

Посмотрел, тоже сыпятся ошибки на отсутствие "svgvectorialreader_rsvg.pas" который я уже нашел в интернете, затем на отсутствие идентификатора "Settings" в строке "SVGVecReader_RSVG_Path := Settings.HelperToolPath;".

zub писал(а):еще есть aggpas он тоже вроде умеет svg, но не проверял

Проверял его, он устарел и умер как мамонты, актуальных ссылок на него нет и нет сомнения что он еще хуже fpvectorial.

Вообще этот path в svg это конечно жесткая тема, вот как здесь можно разобраться:
Код: Выделить всё
<path d="M-177.5,335.9h102.1c0,11.5,0,23.1,0,34.5c-22.6,0.1-45.1-0.1-67.7,0.1c0.1,11-0.2,22,0.1,33c13.4,0.1,26.8,0,40.1,0
      c9.2,8.9,18.4,18.1,27.4,27.1c0.2,15.9,0.1,31.8,0,47.8c-9,9.2-18.2,18.1-27.2,27.3h-47.7c-9-9.1-18.2-18.2-27.2-27.3
      c0-8-0.1-16.1,0-24.1c11.5,0,22.9,0,34.4,0c0,5.6,0,11.2,0,16.8c11.1,0.1,22.2,0.1,33.3,0c0-11,0.1-22,0-33
      c-13.4-0.1-26.8,0-40.2,0c-9.3-8.9-18.1-18.2-27.3-27.2C-177.6,386-177.5,361-177.5,335.9z"/>


Тема с SVG будет становится все актуальнее, щас уже много сайтов переходит на этот формат и это только начало (хотя формату уже много лет, но стал популяризироваться он только сейчас почему-то). Думаю будет для всех полезным если у кого-то получится сделать нормальный рисовальщик, я собираюсь курить спецификацию на предмет того чтобы разобраться со всеми этими обозначениями path, пока навскидку я вообще не понимаю как он составлен. Где тут X, а где Y.. по идеи координаты должны идти парно, а тут постоянно буквы идут.

P.S: нашел ссылки по теме:

1. Спецификация Path в SVG: https://www.w3.org/TR/SVG/paths.html
2. Частичный перевод на русский: https://developer.mozilla.org/ru/docs/Web/SVG/Tutorial/Paths
Moneo
новенький
 
Сообщения: 21
Зарегистрирован: 21.03.2017 17:04:01

Re: SVG: проблема с отрисовкой

Сообщение vitaly_l » 27.05.2017 15:25:42

Moneo писал(а):Что вы имеете ввиду под пустыми областями..чуть подробнее можно?

Например лицо вырезано одной сложной фигурой. Соответственно имеем одну фигуру и пять "дырок", для: двух глаз, рта и двух ноздрей. Если такую фигуру закрасить в канвасе по внешнему контуру, то получится фигура без глаз. Соответственно, дырки на ней рисуются последними и цветом фона. Дырки, как-то обозначаются в файле (как именно не знаю).
Moneo писал(а):Почему умножать, а не делить?

Если нужно в десять раз уменшить то можно разделить на 10, а можно умножить на 0.1 результат одинаковый. Матрицы как правило перемножают.

Да ещё там нужно, всю фигуру сместить в нулевую координату, т.к. в модели сохраняются и отрицательные числа, которые вам ненужны. Для этого находите самое отрицатеьное по Х и самое отрицательное по У. И потом прибавляете модули этих чисел к каждой координате (чтобы рисунок был от ноля до 32 пикселей, а не от -16 до +16). Смещать нужно перед, вычислением масштабирования. Весь рендер можно уложить в два цикла.

Moneo писал(а):Вообще этот path в svg это конечно жесткая тема, вот как здесь можно разобраться:
<path d="M-177.5,335.9h102.1c0,11.5,0,23.1,0,34.5c-22.6,0.1-45.1-0.1-67.7,0.1c0.1,11-0.2,22,0.1,33c13.4,0.1,26.8,0,40.1,0
      c9.2,8.9,18.4,18.1,27.4,27.1c0.2,15.9,0.1,31.8,0,47.8c-9,9.2-18.2,18.1-27.2,27.3h-47.7c-9-9.1-18.2-18.2-27.2-27.3
      c0-8-0.1-16.1,0-24.1c11.5,0,22.9,0,34.4,0c0,5.6,0,11.2,0,16.8c11.1,0.1,22.2,0.1,33.3,0c0-11,0.1-22,0-33
      c-13.4-0.1-26.8,0-40.2,0c-9.3-8.9-18.1-18.2-27.3-27.2C-177.6,386-177.5,361-177.5,335.9z"/>
Тема с SVG будет становится все актуальнее, щас уже много сайтов переходит на этот формат и это только начало (хотя формату уже много лет, но стал популяризироваться он только сейчас почему-то). Думаю будет для всех полезным если у кого-то получится сделать нормальный рисовальщик, я собираюсь курить спецификацию на предмет того чтобы разобраться со всеми этими обозначениями path, пока на вскидку я вообще не понимаю как он составлен. Где тут X, а где Y.. по идеи координаты должны идти парно, а тут постоянно буквы идут.

Вот эти буквы, скорее всего обозначают внешние и внутренние фигуры для рисования. С другой стороны, это может быть какая-то аппроксимация, тогда чуть посложнее, но все описания наверняка есть в модуле: fpvectorialpkg, fpvectorial,fpvtocanvas. Проще всего найдите описание svg, опенсорсное же всё.

Moneo писал(а):P.S: нашел ссылки по теме:
1. Спецификация Path в SVG: https://www.w3.org/TR/SVG/paths.html
2. Частичный перевод на русский: https://developer.mozilla.org/ru/docs/W ... rial/Paths

Вот да, этого более чем достаточно, там указан точный порядок действий. А буквы обозначают какие именно команды нужно задействовать из канваса при рисовании. На час работы (ну или на день).
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение Moneo » 27.05.2017 15:55:58

vitaly_l писал(а):Да ещё там нужно, всю фигуру сместить в нулевую координату, т.к. в модели сохраняются и отрицательные числа, которые вам ненужны. Для этого находите самое отрицатеьное по Х и самое отрицательное по У. И потом прибавляете модули этих чисел к каждой координате (чтобы рисунок был от ноля до 32 пикселей, а не от -16 до +16). Смещать нужно перед, вычислением масштабирования. Весь рендер можно уложить в два цикла.

К каждой отрицательной координате или только к самым большим отрицательным? Похоже про смещение не очень понимаю, надо будет на практике смотреть.

Moneo писал(а):какие именно команды нужно задействовать из канваса при рисовании. На час работы (ну или на день).

Явно не для человека который 2 недели назад впервые услышал про SVG и только начал разбираться с рисовкой не считая курсов инженерной графики в институте которые уже затерлись, но по сути я согласен что ничего невозможного нету..буду изучать данные ссылки и стараться доделать эту задачу. Пару дней щас уйдет на другой функционал более важный, но и к этой задаче к среде я вернусь, до следующих выходных надеюсь сделать.
Moneo
новенький
 
Сообщения: 21
Зарегистрирован: 21.03.2017 17:04:01

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение vitaly_l » 27.05.2017 16:05:01

Moneo писал(а):К каждой отрицательной координате или только к самым большим отрицательным?

Обязательно ко всем координатам фигуры!!! Вначале из всех координат фигуры находите самую отрицательную величину по Х и по У, и потом смещаете все точки во всей фигуре на их модули по Х и по У. Так вы переместите всю фигуру в нулевые координаты. Параллельно, вычисляете самое большое ПОЛУЧИВШЕЕСЯ число по Х и по У. Затем самую большую величину делите на 32. Получаете значение делителя. В итоге, во втором цикле, делите все числа всей фигуры на найденный делитель. Фигура = весь рисунок.
Moneo писал(а):Явно не для человека который 2 недели назад впервые услышал про SVG

Не выдумывайте, главное умом поймите как оно работает и как устроено, а код там очень простой.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение zub » 27.05.2017 18:15:16

Moneo
>>Посмотрел, тоже сыпятся ошибки на
fpvectorial хоть и неактивно пилится, но иногда там проскакивают изменения - поэтому нужно использовать транковую версию и проблем небудет.

>>Проверял его, он устарел и умер как мамонты, актуальных ссылок на него нет и нет сомнения что он еще хуже fpvectorial.
актуальных ссылок на него и ненадо - он в составе лазаря. очень неправильные выводы.

>>Почему умножать, а не делить?
почитайте про преобразования в векторной графике. матрицы - универсальный инструмент, хочешь масштабировать\переносить\поворачивать(или всё сразу) - умножай на матрицу

vitaly_l
>>Соответственно, дырки на ней рисуются последними и цветом фона.
нет. фигура триангулируется и рисуется набор треугольников. в "дырках" не рисуется ничего
>>Не выдумывайте, главное умом поймите как оно работает и как устроено, а код там очень простой.
гдето я это уже слышал))
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение vitaly_l » 27.05.2017 21:00:34

zub писал(а):нет. фигура триангулируется и рисуется набор треугольников. в "дырках" не рисуется ничего

тогда - вообще нет никаких проблем с отрисовкой, только выполнить указания из файла, где какую функцию запустить и дать ей координаты.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение zub » 27.05.2017 21:22:58

vitaly_l
Ок. Сделаешь функцию получающую на вход строчку которая d=, а на выходе отдавать массив координат с модификаторами?
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение vitaly_l » 27.05.2017 22:09:07

zub писал(а):Сделаешь функцию получающую на вход строчку которая d=, а на выходе отдавать массив координат с модификаторами?

zub - а зачем, мне делать эту функцию? И кстати - не вижу вообще ничего сложного в парсинге, строки с модификаторами. Рекомендую разбить парсинг на две функции, одна будет парсить координаты, а вторая разделять строку, на модификаторы и строки для парсинга координат.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SVG: проблема с отрисовкой [Графика, форматы]

Сообщение zub » 27.05.2017 22:14:35

Хз. не всё же флеймить. Какие проблемы если ниче сложного?))
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

Рейтинг@Mail.ru