すだちキャンパス

すだちキャンパス

やってみたこと、学んだことなどのメモ。

画像を分割する方法(Androidアプリ・Kotlin)

こんにちは。
最近KotlinをAndroidアプリ開発のために初めて触ったのですが、そこで詰まったことを簡単にまとめておきます。

やりたい事

画像のように、用意しておいた画像を分割して表示させることです。
Kotlinで画像の分割

表示している画像はこちらからお借りしています。

Bitmapで画像を表示させる

まず調べたところ、画像の操作はBitmapという形式に変換してから行う様でしたのでBitmap形式に変換して表示させてみました。

はじめに、表示させたい画像を用意します。そしてその画像をコピーし、app > res > drawable にペーストします。この時にダイアログが出ますが、OKで大丈夫です。
次に、"activity_main.xml"に移動します。そしてImage Viewをドラッグ&ドロップして表示画面に置きます。この時にエラーが出ると思うのですが、画像のボタンをクリックすれば解消されます。

最後に"MainActivity.kt"に移動してコードを書きます。

package com.example.[アプリ名]

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var imageview = findViewById<ImageView>(R.id.imageView)

        //画像名が"book.png"なら"R.drawable.book"とします
        var bmpImage : Bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.[拡張子無しの画像名])

        imageview.setImageBitmap(bmpImage)
    }
}

ここで1つ注意点があります。それは、「画像のデータサイズが大きすぎるとアプリが落ちる」ということです。
試しに1000KBほどある画像をBitmapとして読み込んで表示しようとすると、画像のようなエラーが出ます。
画像のサイズが大きすぎる場合のエラー

下の方に、
"java.lang.RuntimeException: Canvas: trying to draw too large(167417432bytes) bitmap."
と出ているのが分かると思います。
ちなみに、私はしばらく一番下の"Failed to start monitoring emulator-5554"というエラーにばかり注目していたので解決するのに時間がかかってしまいました。エミュレータの問題ではなく画像のサイズの問題でした・・・。

また調べたところ、ライブラリを使うと大きい画像も表示できるようです。

画像を分割する処理

次に、画像を分割する処理についてです。

Bitmap.createBitmap(元のBitmap画像, x座標, y座標, width, height)

のように書くと、指定した(x,y)座標から指定した幅と高さで切り出して新しいBitmap画像を作成してくれます。
これを利用すると、次のように書けます。(AppCompatActivity()の中の、"setContentView(R.layout.activity_main)"の後から書いています。また、予めImageViewを2つ用意してあります。)

        var imageview = findViewById<ImageView>(R.id.imageView01)
        var imageview2 = findViewById<ImageView>(R.id.imageView02)
        var bmpImage : Bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.book)
        val imageHeight:Int = bmpImage.height
        val imageWidth:Int = bmpImage.width
        val newWidth:Int = imageWidth / 2
        val newHeight:Int = imageHeight
        var x:Int = 0
        var y:Int = 0
        val list = arrayOf(0,1)
        val imageList:MutableList<Bitmap> = mutableListOf()


        for(num in list){
            imageList.add(Bitmap.createBitmap(bmpImage, x, y, newWidth, imageHeight))
            x += newWidth
        }

        imageview.setImageBitmap(imageList[0])
        imageview2.setImageBitmap(imageList[1])

mutableListという可変のListを作成してその中に格納しています。ちなみに、原因は分かりませんがarrayだとアプリが落ちてしまい上手くいきませんでした。

おまけ 画像をスマホ内の写真から選ぶ

こちらの通りにするとできました。
具体的には、onActivityResult()の中身の画像を表示している部分を、上の節で書いたコードに書き換えています。

こんな感じで動きます↓
f:id:sweetgohan:20210123115551g:plain