問題描述
我已經實現了一個在屏幕上顯示相機圖片的簡單應用程序.我現在喜歡做的是抓取一個幀并將其作為位圖處理.據我所知,這并不是一件容易的事.
I've implemented a simple application which shows the camera picture on the screen. What I like to do now is grab a single frame and process it as bitmap. From what I could find out to this point it is not an easy thing to do.
我嘗試使用 onPreviewFrame 方法將當前幀作為字節數組獲取,并嘗試使用 BitmapFactory 類對其進行解碼,但它返回 null.幀的格式是無標題的 YUV,可以轉換為位圖,但在手機上花費的時間太長.此外,我還了解到 onPreviewFrame 方法對運行時有限制,如果耗時過長,應用程序可能會崩潰.
I've tried using the onPreviewFrame method with which you get the current frame as a byte array and tried to decode it with the BitmapFactory class but it returns null. The format of the frame is a headerless YUV which could be translated to bitmap but it takes too long on a phone. Also I've read that the onPreviewFrame method has contraints on the runtime, if it takes too long the application could crash.
那么正確的方法是什么?
So what is the right way to do this?
推薦答案
在 API 17+ 中,您可以使用 'ScriptIntrinsicYuvToRGB' RenderScript 從 NV21 轉換為 RGBA888.這使您無需手動編碼/解碼幀即可輕松處理預覽幀:
In API 17+, you can do conversion to RGBA888 from NV21 with the 'ScriptIntrinsicYuvToRGB' RenderScript. This allows you to easily process preview frames without manually encoding/decoding frames:
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Bitmap bitmap = Bitmap.createBitmap(r.width(), r.height(), Bitmap.Config.ARGB_8888);
Allocation bmData = renderScriptNV21ToRGBA888(
mContext,
r.width(),
r.height(),
data);
bmData.copyTo(bitmap);
}
public Allocation renderScriptNV21ToRGBA888(Context context, int width, int height, byte[] nv21) {
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(nv21.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
in.copyFrom(nv21);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
return out;
}
這篇關于從 Android 中的視頻圖像中獲取幀的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!