Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
392 views
in Technique[技术] by (71.8m points)

android - How to use ScriptIntrinsicYuvToRGB (converting byte[] yuv to byte[] rgba)

I have byte[] yuvByteArray (540x360 image captured from Camera.PreviewCallback.onPreviewFrame method and dumped into assets/yuv.bin file). I want to convert byte[] yuv to byte[] rgba array, using the following code (based on LivePreview android example).

But I receive outBytes rgba array filled with zeros after forEach and copying out allocation to outBytes. What's wrong with my code?


package hellorender; import android.app.Activity; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v8.renderscript.Allocation; import android.support.v8.renderscript.Element; import android.support.v8.renderscript.RenderScript; import android.support.v8.renderscript.ScriptIntrinsicYuvToRGB; import android.support.v8.renderscript.Type; import android.widget.ImageView; import hellorender.R; import java.io.IOException; import java.io.InputStream; public class HelloRenderActivity extends Activity { public static final int W = 540; public static final int H = 360; private RenderScript rs; private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); AssetManager assets = getAssets(); byte[] yuvByteArray = new byte[291600]; byte[] outBytes = new byte[W * H * 4]; InputStream is = null; try { is = assets.open("yuv.bin"); System.out.println("read: " + is.read(yuvByteArray)); } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } ImageView iv = (ImageView) findViewById(R.id.image); rs = RenderScript.create(this); yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.RGBA_8888(rs)); Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)) .setX(W).setY(H) .setYuvFormat(android.graphics.ImageFormat.NV21); 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.copyFrom(yuvByteArray); yuvToRgbIntrinsic.setInput(in); yuvToRgbIntrinsic.forEach(out); out.copyTo(outBytes); Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888); out.copyTo(bmpout); iv.setImageBitmap(bmpout); } } See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

yuv.bin file is definitely in NV21 format, as it captures here http://developer.android.com/reference/android/hardware/Camera.PreviewCallback.html#onPreviewFrame

setYuvFormat method is from API level 18, I removed it

So this code works fine:

rs = RenderScript.create(this);
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));

Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(yuvByteArray.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.copyFrom(yuvByteArray);

yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...