Skip to content

Instantly share code, notes, and snippets.

@LiorA1
Last active May 11, 2020 20:48
Show Gist options
  • Save LiorA1/14263af979ca2fb4cf3d05dc1a19bec3 to your computer and use it in GitHub Desktop.
Save LiorA1/14263af979ca2fb4cf3d05dc1a19bec3 to your computer and use it in GitHub Desktop.
RenderScript: Save YUV_420_888 from Camera2 API to png file in the most efficient way [Uses ScriptIntrinsicYuvToRGB]
// Goal: Save YUV_420_888 from Camera2 API to png file in the most efficient way [Uses ScriptIntrinsicYuvToRGB]
// The following currently produce black image.
// a quick solution will be to use bitmap.
private void saveRenderScript(Image newImage, Context i_Context)
{
final Image image = newImage;
byte[] RGBBytes = ImageUtil.YUV_420_888_toRGBBytesIntrinsics(newImage, i_Context);
FileOutputStream fileOutputStream = null;
try
{
fileOutputStream = new FileOutputStream(_path);
//_path = '/storage/emulated/0/Android/data/com.example.camera2app/files/90529437.png'
fileOutputStream.write(RGBBytes);// write from bytes to _path file !
fileOutputStream.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if(fileOutputStream != null)
{
try
{
fileOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
//And :
public static byte[] YUV_420_888_toRGBBytesIntrinsics(Image image, Context i_Context)
{
if (image == null) return null;
int W = image.getWidth();
int H = image.getHeight();
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] data = new byte[Yb + Ub + Vb];
Y.getBuffer().get(data, 0, Yb);
V.getBuffer().get(data, Yb, Vb);
U.getBuffer().get(data, Yb + Vb, Ub);
// All the image is inside data byte array
// NOTICE: including PixelStrides !
// declaration:
RenderScript rs;
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
// initialization:
rs = RenderScript.create(i_Context);
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
in.copyFromUnchecked(data);
yuvToRgbIntrinsic.setInput(in);// Set the input yuv allocation, must be Element#U8.
yuvToRgbIntrinsic.forEach(out);// Convert the image to RGB.(to 'out' Allocation)
// Advanced Question: How to to know the size needed ?.
final byte[] bytesOut = new byte[out.getBytesSize()];
out.copyTo(bytesOut);
image.close();
return bytesOut;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment