やりたいこと
ある画像から、サムネイルのアイコンを作って表示する処理が必要になったので、Canvasを使って実装してみました。


実際のソースコード
private fun getCroppedBitmap(bitmap: Bitmap): Bitmap {
val size = Math.min(bitmap.width, bitmap.height)
val output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
canvas.drawCircle(size / 2f, size / 2f, size / 2f, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
val max = Math.max(bitmap.width, bitmap.height)
val start = (size - max) / 2
val left = if (bitmap.width < bitmap.height) 0 else start
val top = if (bitmap.height < bitmap.width) 0 else start
val rect = Rect(left, top, bitmap.width + left, bitmap.height + top)
canvas.drawBitmap(bitmap, Rect(0, 0, bitmap.width, bitmap.height), rect, paint)
return output
}
解説
やっていることはそんなに難しくはありません。
まず、出力先のBitmapをsize指定で作成します。この時、sizeは元画像の幅/高さのうち小さい方を指定します。
次にCanvasとPaintを用意します。
今回は円形に画像を切り抜くので、Paintにはジャギーが目立たなくなるようにisAntiAliasをtrueに設定します(詳細はアンチエイリアスを参照のこと)。
canvasは透明で塗りつぶしてから、drawCircle(中心点のx座標,中心点のy座標,半径,paint)
でsizeの半分の半径でちょうど中央に円を描きます。
paint.xfermode
を設定する前のdrawCircleがDST、その後のdrawBitmapがSRCなので、画像が丸の中に入るようにするにはPorterDuffXfermode(PorterDuff.Mode.SRC_IN)
をpaint.xfermode
に設定します。
最後に切り抜くrectを決めてdrawBitmapすることで、描画処理は完了です。