Skip to content

Основы рендеринга

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

Поверхность и Холст

В Skia (и Skija) всё рисование происходит на Холсте (Canvas). Однако холсту нужно место назначения для рисования, которое предоставляется Поверхностью (Surface).

Оффскринный рендеринг (Растровый)

Самый простой способ начать — создать растровую (в памяти) поверхность. Это идеально подходит для генерации изображений, серверного рендеринга или тестирования.

java
// Создаем поверхность размером 100x100 пикселей, используя формат цвета N32 по умолчанию (обычно RGBA или BGRA)
Surface surface = Surface.makeRasterN32Premul(100, 100);

// Получаем Холст с поверхности
Canvas canvas = surface.getCanvas();

Объект Canvas — это ваш основной интерфейс для рисования. Он хранит текущее состояние (трансформации, отсечение) и предоставляет методы рисования.

Использование Кисти (Paint)

В то время как Canvas определяет где и что рисовать, объект Paint определяет как это рисовать. Объект Paint содержит информацию о цветах, стилях обводки, режимах смешивания и различных эффектах.

java
Paint paint = new Paint();
paint.setColor(0xFFFF0000); // Полностью непрозрачный Красный

Работа с цветами

Цвета в Skija представлены в виде 32-битных целых чисел в формате ARGB:

  • 0x за которым следует FF (Альфа), RR (Красный), GG (Зеленый), BB (Синий).
  • 0xFFFF0000 — Непрозрачный Красный.
  • 0xFF00FF00 — Непрозрачный Зеленый.
  • 0xFF0000FF — Непрозрачный Синий.
  • 0x80000000 — Наполовину прозрачный Черный.

Базовые операции рисования

Canvas предоставляет множество методов для рисования примитивов.

java
// Рисуем круг в точке (50, 50) с радиусом 30
canvas.drawCircle(50, 50, 30, paint);

// Рисуем простую линию
canvas.drawLine(10, 10, 90, 90, paint);

// Рисуем прямоугольник
canvas.drawRect(Rect.makeXYWH(10, 10, 80, 80), paint);

Захват и сохранение результата

После рисования на поверхности часто требуется сохранить результат в виде файла изображения.

java
// 1. Делаем снимок текущего содержимого поверхности в виде Изображения (Image)
Image image = surface.makeImageSnapshot();

// 2. Кодируем изображение в определенный формат (например, PNG)
Data pngData = image.encodeToData(EncodedImageFormat.PNG);

// 3. Преобразуем данные в ByteBuffer для записи
ByteBuffer pngBytes = pngData.toByteBuffer();

// 4. Записываем в файл с использованием стандартного Java I/O
try {
    java.nio.file.Path path = java.nio.file.Path.of("output.png");
    Files.write(path, pngBytes.array());
} catch (IOException e) {
    e.printStackTrace();
}

Чтение пикселей (Захват экрана)

Если вам нужны сырые данные пикселей с поверхности (например, для обработки или проверки) без кодирования в формат изображения:

java
// Создаем Bitmap для хранения результата
Bitmap bitmap = new Bitmap();
bitmap.allocPixels(ImageInfo.makeN32Premul(100, 100));

// Читаем пиксели с поверхности в Bitmap
// Это читает всю поверхность, если размеры совпадают
surface.readPixels(bitmap, 0, 0);

// Для определенной области (например, область 50x50, начиная с 10, 10)
Bitmap region = new Bitmap();
region.allocPixels(ImageInfo.makeN32Premul(50, 50));
surface.readPixels(region, 10, 10);

Цепочный API (Fluent API)

Многие сеттеры Skija возвращают this, что позволяет использовать плавный, построительный (builder-style) API:

java
Paint strokePaint = new Paint()
    .setColor(0xFF1D7AA2)
    .setMode(PaintMode.STROKE)
    .setStrokeWidth(2f)
    .setAntiAlias(true);