android.media.Imageとはなにか

# 公式ドキュメント

[Image | Android Developers](https://developer.android.com/reference/android/media/Image.html)

# 使われどころ

Cameraを使った処理（[android.hardware.camera2](https://developer.android.com/reference/android/hardware/camera2/package-summary.html)とか）で画像を取得するとこの形式で取得される。

https://github.com/googlesamples/android-Camera2Basic より

1) [Image取得できたときのイベントリスナ](https://github.com/googlesamples/android-Camera2Basic/blob/0b6a16363b14c452a3af7c4abc0d889bad609507/kotlinApp/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.kt#L152-L158)

```
private val onImageAvailableListener = ImageReader.OnImageAvailableListener {
    backgroundHandler?.post(ImageSaver(it.acquireNextImage(), file))
}
```
- `it.acquireNextImage()`でandroid.media.Imageが取得される。
- [onImageAvailable](https://developer.android.com/reference/android/media/ImageReader.OnImageAvailableListener.html#onImageAvailable(android.media.ImageReader))は新しいImageをImageReaderで読み取れるようになったときのイベント

2) [ImageReaderの初期化処理](https://github.com/googlesamples/android-Camera2Basic/blob/0b6a16363b14c452a3af7c4abc0d889bad609507/kotlinApp/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.kt#L332-L338)

```
imageReader = ImageReader.newInstance(largest.width, largest.height,
                        ImageFormat.JPEG, /*maxImages*/ 2).apply {
                    setOnImageAvailableListener(onImageAvailableListener, backgroundHandler)
```
- `ImageReader.newInstance()`で上のイベントリスナを渡している。
- [ImageReader.newInstance](https://developer.android.com/reference/android/media/ImageReader.html#newInstance(int, int, int, int))の初期化では以下をわたす。
  - int width -> ImageReaderが生成するImageの幅（ピクセル数）
  - int height -> ImageReaderが生成するImageの高さ（ピクセル数）
  - int format -> ImageReaderが生成するImageのフォーマット（[ImageFormat](https://developer.android.com/reference/android/graphics/ImageFormat.html), [PixelFormat](https://developer.android.com/reference/android/graphics/PixelFormat.html) を指定する）
  - maxImages -> アクセスできるようにするImage数

3) [Imageをファイルに保存する処理](https://github.com/googlesamples/android-Camera2Basic/blob/0b6a16363b14c452a3af7c4abc0d889bad609507/kotlinApp/Application/src/main/java/com/example/android/camera2basic/ImageSaver.kt#L11-L47)

```
 val buffer = image.planes[0].buffer
        val bytes = ByteArray(buffer.remaining())
        buffer.get(bytes)
        var output: FileOutputStream? = null
        try {
            output = FileOutputStream(file).apply {
                write(bytes)
            }
        } catch (e: IOException) {
            Log.e(TAG, e.toString())
        } finally {
            image.close()
            output?.let {
                try {
                    it.close()
                } catch (e: IOException) {
                    Log.e(TAG, e.toString())
                }
            }
        }
```
- `Image.planes[0]`をファイルに保存している。

# android.media.Imageとは
- 生成された画像のPixelの情報をBiteBufferとして直接アクセスできるようにするクラス。
- Image自体はメタ情報（高さ、幅など）を取得できるメソッドと、画像の破棄のための`close()`を持っている。
- 実際の画像情報を取得するときは、Imageから[Image.Plane](https://developer.android.com/reference/android/media/Image.Plane.html)を参照する。

# android.media.Image.Planeとは
- 画像データ自体のバイト列にアクセスするためのクラス
- ImageからPlaneの配列が取得できる。
- Planeがいくつかあってそれらがそれぞれどのような意味かは、画像形式によって異なる。