Last active
December 13, 2019 11:21
-
-
Save ryohji/7f124a7759eae1a70f48f63d4cb4f07a to your computer and use it in GitHub Desktop.
Convert `YUV_420_888` format image (from Android Camera2 API) into Jpeg ByteArray (can be used with BitmapFactory.decodeByteArray)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.ImageFormat.NV21 | |
import android.graphics.Rect | |
import android.graphics.YuvImage | |
import android.media.Image | |
import java.io.ByteArrayOutputStream | |
object Converter { | |
fun jpegByteArrayFrom(yuv420_888: Image): ByteArray = | |
yuv420_888.nv21ByteArray | |
.let { YuvImage(it, NV21, yuv420_888.width, yuv420_888.height, null) } | |
.getJpegDataWithQuality(100) | |
private val Image.nv21ByteArray | |
get() = ByteArray(width * height * 3 / 2).also { | |
val vPlane = planes[2] | |
val y = planes[0].buffer.apply { rewind() } | |
val u = planes[1].buffer.apply { rewind() } | |
val v = vPlane.buffer.apply { rewind() } | |
y.get(it, 0, y.capacity()) // copy Y components | |
if (vPlane.pixelStride == 2) { | |
// Both of U and V are interleaved data, so copying V makes VU series but last U | |
v.get(it, y.capacity(), v.capacity()) | |
it[it.size - 1] = u.get(u.capacity() - 1) // put last U | |
} else { // vPlane.pixelStride == 1 | |
var offset = it.size - 1 | |
var i = v.capacity() | |
while (i-- != 0) { // make VU interleaved data into ByteArray | |
it[offset - 0] = u[i] | |
it[offset - 1] = v[i] | |
offset -= 2 | |
} | |
} | |
} | |
private fun YuvImage.getJpegDataWithQuality(quality: Int) = | |
ByteArrayOutputStream().also { | |
compressToJpeg(Rect(0, 0, width, height), quality, it) | |
}.toByteArray() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment