LoginSignup
2
3

More than 3 years have passed since last update.

Canvasを使ってあるBitmapから正円のBitmapを作成する処理を書いた話

Posted at

やりたいこと

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

スクリーンショット 2019-05-06 18.38.46.png
例えばこういうネクタイの画像があったとすると、欲しいのは以下のようなアイコンになります。
スクリーンショット 2019-05-06 18.39.05.png
拡大縮小はせず、中心部分をうまく丸く切り取る処理をする場合、以下のような実装になります。

実際のソースコード

    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することで、描画処理は完了です。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3