【Kotlin】MediaStoreAPIでBitmapを保存する

お絵描きアプリを作ってみました。

お絵描きするViewを作るには以下のGoogleのCodeLabsを参考にすると良いです。

https://developer.android.com/codelabs/advanced-android-kotlin-training-canvas#0

この記事には無いのですが、作成したお絵かきの結果を画像として保存してみたかったので、調べてやってみました。

お絵かきの処理はViewで実施、画像を保存する処理はActivityでやります。

まず、Acitivityで以下のように画像保存する処理を書きます。

Pictureの中に画像が保存されるようにしています。

    @Suppress("DEPRECATION")
    private fun saveImageToStorage(
        bitmap: Bitmap,
        filename: String = "screenshot.jpg",
        mimeType: String =  "image/jpeg",
        directory: String = Environment.DIRECTORY_PICTURES,
        mediaContentUri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    ) {
        val imageOutStream: OutputStream
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val values = ContentValues().apply {
                put(MediaStore.Images.Media.DISPLAY_NAME, filename)
                put(MediaStore.Images.Media.MIME_TYPE, mimeType)
                put(MediaStore.Images.Media.RELATIVE_PATH, directory)
            }

            contentResolver.run {
                val uri =
                    contentResolver.insert(mediaContentUri, values)
                        ?: return
                imageOutStream = openOutputStream(uri) ?: return
            }
        } else {
            val imagePath = Environment.getExternalStoragePublicDirectory(directory).absolutePath
            val image = File(imagePath, filename)
            imageOutStream = FileOutputStream(image)
        }

        imageOutStream.use { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it) }
    }

次に、ボタンが押されたときに上の関数を呼び出します。

class PaintActivity : AppCompatActivity() {
    private lateinit var binding:ActivityPaintBinding
    lateinit var cv:CanvasView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_paint)

        binding = ActivityPaintBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val btnSave = binding.btnImgsave
        cv = binding.canvasview

        btnSave.setOnClickListener {
            saveImageToStorage(cv.getBitmap())
        }
    }

お絵描き用のViewをBindingして持ってきています。

ViewにおけるBitmapを取得する処理は以下の通り。

    fun getBitmap():Bitmap{
        return extraBitmap
    }

Googleフォトアプリで見るとPicturesに保存されているのが確認できました。

参考

https://androidexplained.github.io/android/android11/scoped-storage/2020/09/29/file-saving-android-11.html

https://developer.android.com/codelabs/advanced-android-kotlin-training-canvas#0

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog