在安卓开发当中,如果操作相机预览视频,要处理数据,需要在onPreviewFrame中处理数据,一般给出来的是NV21格式的数据,需要转Bitmap的时候,可以用下面的方法,只要20ms就可以搞定了。
private RenderScript renderScript;
private final ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
private Type.Builder yuvType, rgbaType;
private Allocation in, out;
renderScript = RenderScript.create(context);
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(renderScript, Element.U8_4(renderScript));
public Bitmap NV21ToBitmap(byte [] nv21, int width, int height) {
if (yuvType == null){
yuvType = new Type.Builder(renderScript, Element.U8(renderScript)).setX(nv21.length);
in = Allocation.createTyped(renderScript, yuvType.create(), Allocation.USAGE_SCRIPT);
rgbaType = new Type.Builder(renderScript, Element.RGBA_8888(renderScript)).setX(width).setY(height);
out = Allocation.createTyped(renderScript, rgbaType.create(), Allocation.USAGE_SCRIPT);
}
in.copyFrom(nv21);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
Bitmap bmpout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
out.copyTo(bmpout);
return bmpout;
}
下面的方法,需要100多ms!相差5 倍。
YuvImage image = new YuvImage(bytes, ImageFormat.NV21, previewSize.width, previewSize.height, null);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, stream);
Bitmap bitmap;
if (rotate) {
Bitmap raw = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size(), bitmapOption);
Matrix matrix = new Matrix();
matrix.postRotate(270);
bitmap = Bitmap.createBitmap(raw, 0, 0, raw.getWidth(), raw.getHeight(), matrix, false);
raw.recycle();
} else {
bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size(), bitmapOption);
}
下面的链接,可以高性能旋转位图:
https://stackoverflow.com/questions/12044674/android-rotate-image-without-loading-it-to-memory
使用的是RenderScript旋转。
Bitmap target = Bitmap.createBitmap(height, width, Bitmap.Config.ARGB_8888);
final Allocation targetAllocation = Allocation.createFromBitmap(renderScript, target,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
ScriptC_rotator script = new ScriptC_rotator(renderScript);
script.set_inWidth(width);
script.set_inHeight(height);
Allocation sourceAllocation = Allocation.createFromBitmap(renderScript, bmpout,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
script.set_inImage(sourceAllocation);
script.forEach_rotate_270_clockwise(targetAllocation, targetAllocation);
targetAllocation.copyTo(target);
return target;