Skip to content

Instantly share code, notes, and snippets.

@VictorMotogna
Created April 7, 2020 11:46
Show Gist options
  • Save VictorMotogna/e7a8493af65be994f29f5508660dd4a9 to your computer and use it in GitHub Desktop.
Save VictorMotogna/e7a8493af65be994f29f5508660dd4a9 to your computer and use it in GitHub Desktop.
fun Array<Plane>.YUV_420_888_toRGB(
context: Context,
width: Int,
height: Int
): ByteArray {
// Get the three image planes
val planes: Array<Plane> = this
var buffer: ByteBuffer = planes[0].buffer
buffer.rewind()
val y = ByteArray(buffer.capacity())
buffer.get(y)
buffer = planes[1].buffer
val u = ByteArray(buffer.capacity())
buffer.get(u)
buffer = planes[2].buffer
val v = ByteArray(buffer.capacity())
buffer.get(v)
buffer.clear()
// get the relevant RowStrides and PixelStrides
// (we know from documentation that PixelStride is 1 for y)
val yRowStride = planes[0].rowStride
val uvRowStride =
planes[1].rowStride // we know from documentation that RowStride is the same for u and v.
val uvPixelStride =
planes[1].pixelStride // we know from documentation that PixelStride is the same for u and v.
// rs creation just for demo. Create rs just once in onCreate and use it again.
val rs = RenderScript.create(context)
//RenderScript rs = MainActivity.rs;
val mYuv420 = ScriptC_yuv420888(rs)
// Y,U,V are defined as global allocations, the out-Allocation is the Bitmap.
// Note also that uAlloc and vAlloc are 1-dimensional while yAlloc is 2-dimensional.
val typeUcharY: Type.Builder = Type.Builder(rs, Element.U8(rs))
typeUcharY.setX(yRowStride).setY(height)
val yAlloc = Allocation.createTyped(rs, typeUcharY.create())
yAlloc.copy1DRangeFrom(0, y.size, y)
mYuv420.set_ypsIn(yAlloc)
yAlloc.destroy()
val typeUcharUV: Type.Builder = Type.Builder(rs, Element.U8(rs))
// note that the size of the u's and v's are as follows:
// ( (width/2)*PixelStride + padding ) * (height/2)
// = (RowStride) * (height/2)
typeUcharUV.setX(u.size)
val uAlloc = Allocation.createTyped(rs, typeUcharUV.create())
uAlloc.copyFrom(u)
mYuv420._uIn = uAlloc
val vAlloc = Allocation.createTyped(rs, typeUcharUV.create())
vAlloc.copyFrom(v)
mYuv420._vIn = vAlloc
vAlloc.destroy()
// handover parameters
mYuv420._picWidth = width.toLong()
mYuv420._uvRowStride = uvRowStride.toLong()
mYuv420._uvPixelStride = uvPixelStride.toLong()
val outBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val outAlloc = Allocation.createFromBitmap(
rs,
outBitmap,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT
)
val lo = LaunchOptions()
lo.setX(0, width)
lo.setY(0, height)
mYuv420.forEach_doConvert(outAlloc, lo)
outAlloc.copyTo(outBitmap)
outAlloc.destroy()
val rotatedBitmap = outBitmap.rotateBitmap()
outBitmap.recycle()
val byteArray = rotatedBitmap.toByteArray()
rotatedBitmap.recycle()
return byteArray
}
@LiorA1
Copy link

LiorA1 commented May 11, 2020

Hi
Did you solve it ? (I have an Idea: It can be because repeating calls ? )

@VictorMotogna
Copy link
Author

Hi, yes, I replaced the method with the suggestion from this post

@JuanJoseMoralesCalvo
Copy link

Hi can you post the exact method you are using for the conversion, getting the same error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment