Skip to content

Справочник API: Picture и PictureRecorder

Когда вам нужно рисовать одну и ту же сложную сцену несколько раз — или если у вас есть статичный фон, который не меняется — вам следует использовать Picture. Он записывает ваши команды рисования в высокооптимизированный формат, который Skia может «воспроизводить» гораздо быстрее, чем выполнять отдельные вызовы Java каждый кадр.

Рабочий процесс

Запись картины (Picture) предполагает использование PictureRecorder для получения временного Canvas.

java
PictureRecorder recorder = new PictureRecorder();

// 1. Определите "ограничивающий прямоугольник" (область, которую вы собираетесь нарисовать)
Canvas recordingCanvas = recorder.beginRecording(Rect.makeWH(500, 500));

// 2. Выполняйте команды рисования как обычно
Paint p = new Paint().setColor(0xFF4285F4);
recordingCanvas.drawCircle(250, 250, 100, p);
// ... больше команд рисования ...

// 3. Остановите запись и получите объект Picture
Picture picture = recorder.finishRecordingAsPicture();

API PictureRecorder

PictureRecorder — это объект с состоянием, используемый для захвата команд.

  • beginRecording(bounds): Начинает запись. Возвращает Canvas, в который можно рисовать. Все команды рисования, отправленные на этот холст, будут сохранены.
  • getRecordingCanvas(): Возвращает активный холст для записи или null, если запись не ведется.
  • finishRecordingAsPicture(): Завершает запись и возвращает неизменяемый объект Picture. Делает холст для записи недействительным.
  • finishRecordingAsPicture(cullRect): Завершает запись, но переопределяет ограничивающий прямоугольник, хранящийся в картине.

Создание картин (сериализация)

  • makePlaceholder(cullRect): Создает картину-заполнитель, которая ничего не рисует, но имеет определенные границы.
  • makeFromData(data): Десериализует картину из объекта Data (созданного через serializeToData).

Рисование картины

Как только у вас есть объект Picture, вы можете нарисовать его на любом другом Canvas.

java
canvas.drawPicture(picture);

Зачем использовать Picture?

  1. Производительность: Если у вас есть 1000 вызовов рисования, Java должна вызывать нативный код 1000 раз за кадр. Если вы запишете их в Picture, это будет всего один нативный вызов за кадр.
  2. Потокобезопасность: Хотя Canvas привязан к потоку, Picture является неизменяемым и может быть нарисован из любого потока (хотя обычно вы рисуете его в основном потоке рендеринга).
  3. Кэширование тесселяции: Skia может кэшировать сложную геометрию (например, пути) внутри Picture лучше, чем для отдельных вызовов.

Лучшие практики и подводные камни

  • Не записывайте всё подряд: Если ваш контент меняется каждый кадр (например, движущийся персонаж), запись нового Picture каждый раз может оказаться медленнее из-за накладных расходов на работу рекордера.
  • Время жизни Canvas: Canvas, который вы получаете из beginRecording(), действителен только до вызова finishRecordingAsPicture(). Не пытайтесь сохранить на него ссылку!
  • Память: Картины занимают нативную память. Если вы создаете много маленьких картин, не забудьте close() их, когда они больше не нужны.