Upgrade to Pro — share decks privately, control downloads, hide ads and more …

角丸? それxfermodeで出来るよ

daimarom
August 21, 2020

角丸? それxfermodeで出来るよ

YUMEMI.apk #1で発表した資料です
https://yumemi.connpass.com/event/180842/

daimarom

August 21, 2020
Tweet

More Decks by daimarom

Other Decks in Programming

Transcript

  1. Androidにおける角丸の実現方法
 • AndroidXのCardViewを使う
 • AndroidXのRoundedBitmapDrawableを使う
 • BitmapShaderとdrawRoundRectの組み合わせでBitmapを加工する
 • clipRectで描画領域を切り抜く
 •

    画像で表現する
 • xfermodeにPorterDuff.Mode.CLEARなPorterDuffXfermodeを設定して、角丸矩形の 範囲外を塗りつぶす(消去する) <- コレをご紹介

  2. xfermode
 Xfermode is the base class for objects that are

    called to implement custom "transfer-modes" in the drawing pipeline. The static function Create(Modes) can be called to return an instance of any of the predefined subclasses as specified in the Modes enum. When an Xfermode is assigned to an Paint, then objects drawn with that paint have the xfermode applied.
 
 描画パイプラインでカスタムの "転送モード" を実装するために呼び出されるオブジェク トの基底クラス
 https://developer.android.com/reference/android/graphics/Xfermode

  3. PorterDuffXfermode
 カスタムの "転送モード" を実装したクラス
 
 1984年に発表された "Compositing Digital Images". の著者

    Thomas Porter と Tom Duff にちなんで命名
 
 Androidにおいては、
 本論文で説明されている12のルールを総称して
 アルファ合成モードと呼ぶ
 https://developer.android.com/reference/android/graphics/PorterDuff.Mode#CLEAR

  4. PorterDuff.Mode.CLEAR
 Destination pixels covered by the source are cleared to

    0. 
 
 PorterDuff.Mode.CLEARを指定したpaintを用意し、角丸矩形の範囲外を指定したpathを 対象に描画すればよさそう
 
 https://developer.android.com/reference/android/graphics/PorterDuff.Mode#CLEAR

  5. 実践
 わ た し は 指 定 さ れ た

    P a t h 領 域 の ピ ク セ ル を 消 去 し て う ま れ た 角 丸 V i e w こ ん ご と も よ ろ し く ・ ・ ・
  6. 実践(コード)
 override fun draw(canvas: Canvas) { super.draw(canvas) canvas.drawPath(clearPath, clearPaint) }

    /** 塗りつぶし(消去)用の Paintを作成 */ private val clearPaint = Paint().apply { isAntiAlias = true xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) } /** 矩形角丸範囲外を表す Pathを作成 */ private val clearPath get() = Path().apply { // Canvasサイズと縦横幅が同じで、角丸加工した RoundRectを設定 addRoundRect(canvasRect, cornerRadius, cornerRadius, Path.Direction.CW) // RoundRectの範囲外部分を塗りつぶし対象とする fillType = Path.FillType.INVERSE_WINDING } ->