我正在尝试将Android相机Feed转换为位图以进行图像处理.
我有一些代码可以在原生java中将YUV转换为RGB,但是,这个过程对于实时视频来说不够快,所以我认为在应用过滤器之前我需要在C或C中转换它.我已经设置了NDK并且正在工作,所以我不知道该怎么做才将以下代码移植到C或C:
// decode Y, U, and V values on the YUV 420 buffer described as ycbcr_422_SP by AndroID // DavID Manpearl 081201 public voID decodeYUV(int[] out, byte[] fg, int wIDth, int height) throws NullPointerException, IllegalArgumentException { int sz = wIDth * height; if (out == null) throw new NullPointerException("buffer out is null"); if (out.length < sz) throw new IllegalArgumentException("buffer out size " + out.length + " < minimum " + sz); if (fg == null) throw new NullPointerException("buffer 'fg' is null"); if (fg.length < sz) throw new IllegalArgumentException("buffer fg size " + fg.length + " < minimum " + sz * 3 / 2); int i, j; int Y, Cr = 0, Cb = 0; for (j = 0; j < height; j++) { int pixPtr = j * wIDth; final int jdiv2 = j >> 1; for (i = 0; i < wIDth; i++) { Y = fg[pixPtr]; if (Y < 0) Y += 255; if ((i & 0x1) != 1) { final int cOff = sz + jdiv2 * wIDth + (i >> 1) * 2; Cb = fg[cOff]; if (Cb < 0) Cb += 127; else Cb -= 128; Cr = fg[cOff + 1]; if (Cr < 0) Cr += 127; else Cr -= 128; } int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); if (R < 0) R = 0; else if (R > 255) R = 255; int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); if (G < 0) G = 0; else if (G > 255) G = 255; int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); if (B < 0) B = 0; else if (B > 255) B = 255; out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; } }}
…
decodeYUV(argb8888, data, camSize.wIDth, camSize.height);Bitmap bitmap = Bitmap.createBitmap(argb8888, camSize.wIDth, camSize.height, Config.ARGB_8888);
有谁知道如何做到这一点?
非常感谢!
更新
这是我有多远:
JNIEXPORT voID JNICALL Java_com_twothreetwo_zoomplus_ZoomPlus_YUVtoRGB(jnienv * env, jobject obj, jintArray rgb, jbyteArray yuv420sp, jint wIDth, jint height){ int sz; int i; int j; int Y; int Cr = 0; int Cb = 0; int pixPtr = 0; int jdiv2 = 0; int R = 0; int G = 0; int B = 0; int cOff; sz = wIDth * height; //if(out == null) throw new NullPointerException("buffer 'out' is null"); //if(out.length < sz) throw new IllegalArgumentException("buffer 'out' size " + out.length + " < minimum " + sz); //if(fg == null) throw new NullPointerException("buffer 'fg' is null"); //if(fg.length < sz) throw new IllegalArgumentException("buffer 'fg' size " + fg.length + " < minimum " + sz * 3/ 2); for(j = 0; j < height; j++) { pixPtr = j * wIDth; jdiv2 = j >> 1; for(i = 0; i < wIDth; i++) { Y = yuv420sp[pixPtr]; if(Y < 0) Y += 255; if((i & 0x1) != 1) { cOff = sz + jdiv2 * wIDth + (i >> 1) * 2; Cb = yuv420sp[cOff]; if(Cb < 0) Cb += 127; else Cb -= 128; Cr = yuv420sp[cOff + 1]; if(Cr < 0) Cr += 127; else Cr -= 128; } R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); if(R < 0) R = 0; else if(R > 255) R = 255; G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); if(G < 0) G = 0; else if(G > 255) G = 255; B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); if(B < 0) B = 0; else if(B > 255) B = 255; rgb[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; } }}
但我得到以下C错误:
apps/zoomplusndk/jni/zoomplusndk.c:53: warning: dereferencing 'voID *' pointerapps/zoomplusndk/jni/zoomplusndk.c:53: error: voID value not ignored as it ought to beapps/zoomplusndk/jni/zoomplusndk.c:56: warning: dereferencing 'voID *' pointerapps/zoomplusndk/jni/zoomplusndk.c:56: error: voID value not ignored as it ought to beapps/zoomplusndk/jni/zoomplusndk.c:58: warning: dereferencing 'voID *' pointerapps/zoomplusndk/jni/zoomplusndk.c:58: error: voID value not ignored as it ought to beapps/zoomplusndk/jni/zoomplusndk.c:67: warning: dereferencing 'voID *' pointerapps/zoomplusndk/jni/zoomplusndk.c:67: error: invalID use of voID Expression
第53行是Y = yuv420sp [pixPtr]; if(Y <0)Y = 255;
解决方法:
这是你的代码更正:
#include <jni.h>#include <androID/log.h>int* rgbData;int rgbDataSize = 0;JNIEXPORT voID JNICALL Java_mk_g6_transparency_CameraPrevIEw_YUVtoRBG(jnienv * env, jobject obj, jintArray rgb, jbyteArray yuv420sp, jint wIDth, jint height){ int sz; int i; int j; int Y; int Cr = 0; int Cb = 0; int pixPtr = 0; int jdiv2 = 0; int R = 0; int G = 0; int B = 0; int cOff; int w = wIDth; int h = height; sz = w * h; jbyte* yuv = yuv420sp; if(rgbDataSize < sz) { int tmp[sz]; rgbData = &tmp[0]; rgbDataSize = sz; __androID_log_write(ANDROID_LOG_INFO, "JNI", "alloc"); } for(j = 0; j < h; j++) { pixPtr = j * w; jdiv2 = j >> 1; for(i = 0; i < w; i++) { Y = yuv[pixPtr]; if(Y < 0) Y += 255; if((i & 0x1) != 1) { cOff = sz + jdiv2 * w + (i >> 1) * 2; Cb = yuv[cOff]; if(Cb < 0) Cb += 127; else Cb -= 128; Cr = yuv[cOff + 1]; if(Cr < 0) Cr += 127; else Cr -= 128; } R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); if(R < 0) R = 0; else if(R > 255) R = 255; G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); if(G < 0) G = 0; else if(G > 255) G = 255; B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); if(B < 0) B = 0; else if(B > 255) B = 255; rgbData[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; } } (*env)->SetIntArrayRegion(env, rgb, 0, sz, ( jint * ) &rgbData[0] );}
它也在http://dl.dropbox.com/u/49855874/yuv-decoder.c在线
我的测试:
> 640×480的相机预览在HTC Desire上处理~20ms
>相机预览为320×240,HTC Desire处理~6ms
以上是内存溢出为你收集整理的android – 使用NDK将YUV解码为C/C++中的RGB全部内容,希望文章能够帮你解决android – 使用NDK将YUV解码为C/C++中的RGB所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)