Last active
May 11, 2020 20:48
-
-
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]
This file contains 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
// 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