キャンバスにレイヤ化された画像を表示する

ソース画像をブレンドまたはオーバーレイして、キャンバスにレイヤ化された画像を表示できます。たとえば、個別のバックグラウンド ドローアブルとフォアグラウンド ドローアブルを組み合わせることで、Android フレームワークがアプリアイコンを生成する方法を再現できます。レイヤ化された画像を表示するには、次の操作を行う必要があります。

  • キャンバスに画像を重ねて表示する。
  • ソースをオーバーレイします。

バージョンの互換性

この実装では、プロジェクトの minSDK を API レベル 21 以上に設定する必要があります。

依存関係

キャンバスに画像を重ねる

次のコードは、2 つのソース画像を重ね合わせて、キャンバスにブレンド画像をレンダリングします。

class OverlayImagePainter constructor(
    private val image: ImageBitmap,
    private val imageOverlay: ImageBitmap,
    private val srcOffset: IntOffset = IntOffset.Zero,
    private val srcSize: IntSize = IntSize(image.width, image.height),
    private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height)
) : Painter() {

    private val size: IntSize = validateSize(srcOffset, srcSize)
    override fun DrawScope.onDraw() {
        // draw the first image without any blend mode
        drawImage(
            image,
            srcOffset,
            srcSize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            )
        )
        // draw the second image with an Overlay blend mode to blend the two together
        drawImage(
            imageOverlay,
            srcOffset,
            overlaySize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            ),
            blendMode = BlendMode.Overlay
        )
    }

    /**
     * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height
     */
    override val intrinsicSize: Size get() = size.toSize()

    private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize {
        require(
            srcOffset.x >= 0 &&
                srcOffset.y >= 0 &&
                srcSize.width >= 0 &&
                srcSize.height >= 0 &&
                srcSize.width <= image.width &&
                srcSize.height <= image.height
        )
        return srcSize
    }
}

コードに関する主なポイント

  • OverlayImagePainter を使用します。これは、ソース画像の上に画像をオーバーレイするために使用できるカスタム Painter 実装です。ブレンドモードは、画像の結合方法を制御します。最初の画像は他の画像を上書きしないため、ブレンドモードは必要ありません。2 番目の画像の Overlay ブレンドモードは、2 番目の画像で覆われている 1 番目の画像の領域を上書きします。
  • DrawScope.onDraw() がオーバーライドされ、この関数で 2 つの画像が重ね合わされます。
  • intrinsicSize がオーバーライドされ、結合画像の固有のサイズが正しく報告されるようになりました。

ソース画像をオーバーレイする

このカスタム ペインタ Painter を使用すると、次のように元の画像の上に画像を重ねることができます。

val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow)
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)
val customPainter = remember {
    OverlayImagePainter(dogImage, rainbowImage)
}
Image(
    painter = customPainter,
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier.wrapContentSize()
)

コードに関する主なポイント

  • 結合する画像は、OverlayImagePainter を使用して結合される前に、それぞれ ImageBitmap インスタンスとして読み込まれます。
  • 結合された画像は、レンダリング時にカスタム ペインターを使用してソース画像を結合する Image コンポーザブルによってレンダリングされます。

結果

2 つの画像を重ね合わせて表示するカスタム ペインタ
図 1: カスタム Painter を使用して、犬の画像に半透明のレインボー画像を重ね合わせる Image

このガイドを含むコレクション

このガイドは、Android 開発の幅広い目標を網羅する、厳選されたクイックガイド コレクションの一部です。

明るく魅力的なビジュアルを使用して、Android アプリの外観を美しくする手法について学びます。

ご質問やフィードバックがある場合

よくある質問のページでクイックガイドをご覧になるか、お問い合わせフォームからご意見をお寄せください。