Delphi и EPS
Векторная графика
В этой статье мы рассмотрим простой программный способ создания векторных изображений. Иногда возникает необходимость создания картинок (например, построение графиков) для наблюдения
Разрабатывая одну программу на Delphi, я оказался в похожей ситуации. Сначала я сделал экспорт в BMP размером 10000*10000. Но это не самое красивое и удобное решение, и я захотел перейти к векторным изображениям. Встроенных средств для работы с векторной графикой в Delphi нет. Бесплатных дополнений я не нашел. Мне пришлось написать свою библиотечку.
Проще всего работать с текстовыми векторными форматами. Я выбирал между SVG и EPS. Первый формат новее, поддерживает больше возможностей (например, в нем есть градиенты, в отличие от EPS). Поддержка второго формата шире. Я выбрал именно EPS, поскольку картинки в этом формате можно напрямую использовать в TeX. Но описанный метод можно применить для любого текстового формата.
Еще одно достоинство векторных форматов — их можно просматривать в специальных программах, приближать отдельные области и т. д. При этом у программы, создавшей такой файл, совсем не обязательно делать графический интерфейс.
Библиотека delphi_eps
Чтение обзора формата EPS и просмотр простых
Итак, просматривая простейший
gsave
1 0 0 setrgbcolor
newpath
141 301 moveto
131 311 lineto
141 321 lineto
141 301 lineto
closepath
fill
grestore
Команда setrgbcolor отвечает за цвет заливки. Три числа — доли красного, зеленого и синего цвета (от 0 до 1). Вершины многоугольника задаются командами moveto и lineto.
Команды вроде setrgbcolor или lineto мы будем хранить в шаблоне — текстовом файле. Вот его фрагмент:
<!-- filled_polygon -->
gsave
*COLOR*
newpath
*BODY*
closepath
fill
grestore
<!-- filled_polygon -->
<!-- lineto -->
*X* *Y* lineto
<!-- lineto -->
<!-- moveto -->
*X* *Y* moveto
<!-- moveto -->
<!-- color -->
*R* *G* *B* setrgbcolor
<!-- color -->
Этот файл легко прочитать (функции explode и str_replace максимально приближены к аналогичным функциям из PHP: первая разбивает строку на части по разделителю, а вторая производит замену одной подстроки на другую):
var
sa, sa2: TStrings;
s: string;
...
s := '';
sa := TStringList.Create;
try
sa.LoadFromFile(filename);
s := sa.text;
finally
sa.Free;
end;
s := str_replace(#10, '', s);
sa2 := explode('<!-- filled_polygon -->', s);
if sa2.Count <> 3 then
exit;
polygon_pattern := trim(sa2[1]) + #13;
sa2.Free;
sa2 := explode('<!-- lineto -->', s);
if sa2.Count <> 3 then
exit;
lineto_pattern := trim(sa2[1]) + #13;
sa2.Free;
sa2 := explode('<!-- moveto -->', s);
if sa2.Count <> 3 then
exit;
moveto_pattern := trim(sa2[1]) + #13;
sa2.Free;
Когда шаблоны прочитаны, в них легко вставить настоящие данные:
type
TPointF = record
x, y: double;
end;
procedure TEPS.SetFillColor(const r, g, b: double);
begin
fill_color := color_pattern;
fill_color := str_replace('*R*', MyFloatToStr(r), fill_color);
fill_color := str_replace('*G*', MyFloatToStr(g), fill_color);
fill_color := str_replace('*B*', MyFloatToStr(b), fill_color);
end;
procedure TEPS.FillPolygon(const points: array of TPointF);
var
i: integer;
s, current_path: string;
begin
if Length(points) < 2 then
exit;
s := moveto_pattern;
s := str_replace('*X*', MyFloatToStr(points[0].x), s);
s := str_replace('*Y*', MyFloatToStr(points[0].y), s);
current_path := s;
for i := Length(points) - 1 downto 0 do
begin
s := lineto_pattern;
s := str_replace('*X*', MyFloatToStr(points[i].x), s);
s := str_replace('*Y*', MyFloatToStr(points[i].y), s);
current_path := current_path + s;
end;
s := str_replace('*BODY*', current_path, polygon_pattern);
s := str_replace('*COLOR*', fill_color, s);
current_body := current_body + s;
end;
Переменная fill_color содержит текущий цвет заполнения областей. В переменной current_body собирается всё «тело»
Теперь достаточно вызвать следующую последовательность команд, чтобы нарисовать красный треугольник, с которого мы и начали рассмотрение:
var
tr: array[0..2] of TPointF;
...
eps.SetFillColor(1, 0, 0);
tr[0].x := 141;
tr[0].y := 301;
tr[1].x := 141;
tr[1].y := 321;
tr[2].x := 131;
tr[2].y := 311;
eps.FillPolygon(tr);
Библиотечка содержит простейшие функции — рисование ломаных и многоугольников. Но ее легко расширять и дополнять нужными функциями, содержащимися в EPS (например, кривые Безье).
В архиве с библиотечкой есть пример использования, более приближенный к реальности. Мне
Скачать
delphi_eps.zip, 3 Кб.
Оставьте свой комментарий