Основы рендеринга
Это руководство охватывает фундаментальные концепции рендеринга с использованием Skija, от создания поверхности для рисования до выполнения базовых операций рисования.
Поверхность и Холст
В Skia (и Skija) всё рисование происходит на Холсте (Canvas). Однако холсту нужно место назначения для рисования, которое предоставляется Поверхностью (Surface).
Оффскринный рендеринг (Растровый)
Самый простой способ начать — создать растровую (в памяти) поверхность. Это идеально подходит для генерации изображений, серверного рендеринга или тестирования.
// Создаем поверхность размером 100x100 пикселей, используя формат цвета N32 по умолчанию (обычно RGBA или BGRA)
Surface surface = Surface.makeRasterN32Premul(100, 100);
// Получаем Холст с поверхности
Canvas canvas = surface.getCanvas();Объект Canvas — это ваш основной интерфейс для рисования. Он хранит текущее состояние (трансформации, отсечение) и предоставляет методы рисования.
Использование Кисти (Paint)
В то время как Canvas определяет где и что рисовать, объект Paint определяет как это рисовать. Объект Paint содержит информацию о цветах, стилях обводки, режимах смешивания и различных эффектах.
Paint paint = new Paint();
paint.setColor(0xFFFF0000); // Полностью непрозрачный КрасныйРабота с цветами
Цвета в Skija представлены в виде 32-битных целых чисел в формате ARGB:
0xза которым следуетFF(Альфа),RR(Красный),GG(Зеленый),BB(Синий).0xFFFF0000— Непрозрачный Красный.0xFF00FF00— Непрозрачный Зеленый.0xFF0000FF— Непрозрачный Синий.0x80000000— Наполовину прозрачный Черный.
Базовые операции рисования
Canvas предоставляет множество методов для рисования примитивов.
// Рисуем круг в точке (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);Захват и сохранение результата
После рисования на поверхности часто требуется сохранить результат в виде файла изображения.
// 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();
}Чтение пикселей (Захват экрана)
Если вам нужны сырые данные пикселей с поверхности (например, для обработки или проверки) без кодирования в формат изображения:
// Создаем 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:
Paint strokePaint = new Paint()
.setColor(0xFF1D7AA2)
.setMode(PaintMode.STROKE)
.setStrokeWidth(2f)
.setAntiAlias(true);