Brush API

Ink Brush API 可用於建立及自訂畫布上的繪圖筆刷。

建立筆刷

如要建立筆刷,請使用 Brush 工廠方法和具名引數,例如 Brush.createWithColorLong()。這個類別可讓您設定下列屬性:

  • family:筆刷的樣式,類似於文字中的字體或字型。如要查看可用的 BrushFamily 值,請參閱 StockBrushes
  • color:筆刷顏色。您可以使用 ColorLong 設定顏色。
  • size:使用筆刷建立的筆觸基本粗細。
  • epsilon:筆劃中兩個點必須視為不同的最小距離,可控制筆劃幾何的詳細程度或精確度。
    • 值越高,筆觸就越簡化,記憶體用量越少,算繪速度越快,但放大時可能會出現鋸齒狀邊緣等明顯的瑕疵。
    • 值越小,高品質縮放時保留的細節就越多,但記憶體用量會增加。
    • 如要使用 1 像素單位比例製作原型,建議從 0.1 開始。 對於支援各種螢幕密度的正式版應用程式,請使用密度獨立單位 (例如 dp),並據此調整 epsilon。
val redBrush = Brush.createWithColorLong(
  family = StockBrushes.pressurePen(),
  colorLong = Color.RED.pack(),
  size = 5F,
  epsilon = 0.1F
)

修改筆刷屬性

您可以使用 copy() 方法建立現有筆刷的副本。這個方法可讓您變更筆刷的任何屬性。

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

自訂筆刷

While StockBrushes provides a versatile set of common brushes, Ink API also offers an advanced path for creating entirely new brush behaviors for unique artistic effects or to replicate specific existing brushes for backward compatibility.

A custom BrushFamily is loaded from its serialized format. The required format is the gzipped binary encoding of the BrushFamily protocol buffer. This lets you load and use custom brush files today. Once deserialized, the custom BrushFamily can be used to create a new Brush with a specific color and size, just like any of the StockBrushes families.

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
)