dlib — это мощная и удобная библиотека для языка программирования D, предназначенная для работы с изображениями. В этой статье мы рассмотрим, как создать проект с использованием dlib, добавить зависимости, протестировать проект с примером создания изображения и реализовать основные графические примитивы, такие как линии (с использованием алгоритмов DDA и Брезенхэма), окружности, конические сечения, прямоугольники и закрашенные версии окружностей и прямоугольников. Дополнительно мы рассмотрим, как нарисовать правильный n-угольник.
Пример создания изображения
Создадим простой пример, который создаёт изображение и сохраняет его в файл.
Код для создания изображения
import dlib.image;
import dlib.image.io;
void main()
{
// Создаем изображение размером 100x100 пикселей
auto img = Image!(RGB, ubyte)(100, 100);
// Заполняем изображение белым цветом
img[] = RGB(255, 255, 255);
// Сохраняем изображение в файл
savePNG(img, "output.png");
}
Запустим наш проект:
dub run
В результате должен появиться файл output.png
с изображением размером 100×100 пискелей, полностью заполненным белым цветом.
Реализация графических примитивов
Линии
Алгоритм DDA
void drawLineDDA(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
int dx = x2 - x1;
int dy = y2 - y1;
int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
float xIncrement = dx / float(steps);
float yIncrement = dy / float(steps);
float x = x1;
float y = y1;
for (int i = 0; i <= steps; i++)
{
img[cast(int)x, cast(int)y] = color;
x += xIncrement;
y += yIncrement;
}
}
Алгоритм Брезенхэма
void drawLineBresenham(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int sx = x1 < x2 ? 1 : -1;
int sy = y1 < y2 ? 1 : -1;
int err = dx - dy;
while (true)
{
img[x1, y1] = color;
if (x1 == x2 && y1 == y2) break;
int e2 = 2 * err;
if (e2 > -dy) { err -= dy; x1 += sx; }
if (e2 < dx) { err += dx; y1 += sy; }
}
}
Окружности
Алгоритм Брезенхэма
void drawCircle(Image!(RGB, ubyte) img, int xc, int yc, int r, RGB color)
{
int x = 0;
int y = r;
int d = 3 - 2 * r;
drawCirclePoints(img, xc, yc, x, y, color);
while (y >= x)
{
x++;
if (d > 0)
{
y--;
d = d + 4 * (x - y) + 10;
}
else
{
d = d + 4 * x + 6;
}
drawCirclePoints(img, xc, yc, x, y, color);
}
}
void drawCirclePoints(Image!(RGB, ubyte) img, int xc, int yc, int x, int y, RGB color)
{
img[xc + x, yc + y] = color;
img[xc - x, yc + y] = color;
img[xc + x, yc - y] = color;
img[xc - x, yc - y] = color;
img[xc + y, yc + x] = color;
img[xc - y, yc + x] = color;
img[xc + y, yc - x] = color;
img[xc - y, yc - x] = color;
}
Прямоугольники
void drawRectangle(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
for (int x = x1; x <= x2; x++)
{
img[x, y1] = color;
img[x, y2] = color;
}
for (int y = y1; y <= y2; y++)
{
img[x1, y] = color;
img[x2, y] = color;
}
}
Закрашенные окружности и прямоугольники
Закрашенная окружность
void fillCircle(Image!(RGB, ubyte) img, int xc, int yc, int r, RGB color)
{
for (int y = -r; y <= r; y++)
{
for (int x = -r; x <= r; x++)
{
if (x * x + y * y <= r * r)
{
img[xc + x, yc + y] = color;
}
}
}
}
Закрашенный прямоугольник
void fillRectangle(Image!(RGB, ubyte) img, int x1, int y1, int x2, int y2, RGB color)
{
for (int y = y1; y <= y2; y++)
{
for (int x = x1; x <= x2; x++)
{
img[x, y] = color;
}
}
}
Правильный n-угольник
import std.math : cos, sin, PI;
void drawPolygon(Image!(RGB, ubyte) img, int xc, int yc, int r, int n, RGB color)
{
double angleStep = 2 * PI / n;
int[] xPoints = new int[n];
int[] yPoints = new int[n];
for (int i = 0; i < n; i++)
{
xPoints[i] = xc + cast(int)(r * cos(i * angleStep));
yPoints[i] = yc + cast(int)(r * sin(i * angleStep));
}
for (int i = 0; i < n; i++)
{
int nextIndex = (i + 1) % n;
drawLineBresenham(img, xPoints[i], yPoints[i], xPoints[nextIndex], yPoints[nextIndex], color);
}
}
Автор статьи:
Обновлено:
Добавить комментарий