Interfejsy Brush API

Interfejsy BrushInk API umożliwiają tworzenie i dostosowywanie pędzli do rysowania na obszarze roboczym.

Tworzenie pędzla

Aby utworzyć pędzel, użyj metod fabrycznych Brush z argumentami nazwanymi, takimi jak Brush.createWithColorLong(). Ta klasa umożliwia ustawienie tych właściwości:

  • family: styl pędzla, analogiczny do kroju lub czcionki w tekście. Dostępne wartości znajdziesz w sekcji StockBrushes.BrushFamily
  • color: kolor pędzla. Kolor możesz ustawić za pomocą ColorLong.
  • size: podstawowa grubość pociągnięć pędzla.
  • epsilon: najmniejsza odległość, przy której 2 punkty w pociągnięciu muszą być uznawane za różne. Określa poziom szczegółowości lub wierności geometrii pociągnięcia.
    • Wyższe wartości bardziej upraszczają pociągnięcie, co zmniejsza wykorzystanie pamięci i przyspiesza renderowanie, ale może powodować widoczne artefakty, takie jak poszarpane krawędzie po powiększeniu.
    • Niższe wartości zachowują więcej szczegółów podczas powiększania w wysokiej jakości, ale zwiększają zużycie pamięci.
    • W przypadku prototypowania ze skalą jednostki 1 piksela dobrym punktem wyjścia jest wartość 0, 1. W przypadku aplikacji produkcyjnych obsługujących różne gęstości ekranu używaj jednostek niezależnych od gęstości (np. dp) i odpowiednio dostosuj wartość epsilon.
val redBrush = Brush.createWithColorLong(
  family = StockBrushes.pressurePen(),
  colorLong = Color.RED.pack(),
  size = 5F,
  epsilon = 0.1F
)

Modyfikowanie właściwości pędzla

Możesz utworzyć kopię istniejącego pędzla za pomocą metody copy(). Ta metoda umożliwia zmianę dowolnej właściwości pędzla.

val blueBrush = redBrush.copy(colorLong = Color.BLUE.pack())

Pędzle niestandardowe

虽然 StockBrushes 提供了一组通用的多功能笔刷,但 Ink API 还提供了一种高级方法,用于创建全新的笔刷行为,以实现独特的艺术效果,或复制特定的现有笔刷以实现向后兼容性。

自定义 BrushFamily 从其序列化格式加载。所需格式为 BrushFamily 协议缓冲区的 gzip 压缩二进制编码。这样一来,您就可以立即加载和使用自定义笔刷文件。反序列化后,自定义 BrushFamily 可用于创建具有特定颜色和大小的新 Brush,就像任何 StockBrushes 系列一样。

class CustomBrushes(val context: Context) {

  private const val TAG = "CustomBrushes"

  val brushes by lazy { loadCustomBrushes(context) }

  @OptIn(ExperimentalInkCustomBrushApi::class)
  private fun loadCustomBrushes(): List<CustomBrush> {
    val brushFiles = mapOf(
        "Calligraphy" to (R.raw.calligraphy to R.drawable.draw_24px),
        "Flag Banner" to (R.raw.flag_banner to R.drawable.flag_24px),
        "Graffiti" to (R.raw.graffiti to R.drawable.format_paint_24px),
    // ...
    )

    val loadedBrushes = brushFiles.mapNotNull { (name, pair) ->
      val (resourceId, icon) = pair
      val brushFamily = context.resources.openRawResource(resourceId).use
      { inputStream ->
          BrushFamily.decode(inputStream)
      }
      CustomBrush(name, icon, brushFamily.copy(clientBrushFamilyId = name))     
    }
    return loadedBrushes
  }
}

data class CustomBrush(
  val name: String,
  val icon: Int,
  val brushFamily: BrushFamily
)