android在jni中对SurfaceView显示一张图片

来源:互联网 发布:android程序员出路 编辑:程序博客网 时间:2024/05/21 07:51

大致流程是,在java获得Bitmap 的相素值,再通过getSurface()拿到Surface,一起传到jni,在jni就可以直接用了。

遇到一个坑就是在荣耀7.0手机上,图片大了不行运行,目前还没找到原因,如有朋友知道可以给我留言。谢谢!


public class SurfaceActivity extends Activity{    private MSurfaceView yuvsurfaceview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getWindow().requestFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_view);               yuvsurfaceview = (MSurfaceView) findViewById(R.id.tSurfaceView);    }}


这是surfaceview


public class MSurfaceView extends SurfaceView implements SurfaceHolder.Callback{ private SurfaceHolder mHolder; private Jni jni; private Bitmap bitmap; private int width, height;public MSurfaceView(Context context) {this(context, null, 0);// TODO Auto-generated constructor stub}public MSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);// TODO Auto-generated constructor stub}
public MSurfaceView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubjni = new Jni();        mHolder = this.getHolder();        mHolder.addCallback(this);    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.rongrong);         width = bitmap.getWidth();    height = bitmap.getHeight();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int arg1, int width, int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stub//把surfce传到Jni画图        int[] pixels = new int[width * height];        System.out.println("Width : " + width + ", height : " + height);        //把位图的数据拷贝到pixels[]中        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);               //初始化jni.setSurface(holder.getSurface(), pixels, width, height); }@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub}       public Surface getSurface() {        SurfaceHolder holder = getHolder();        if (holder != null) {            return holder.getSurface();        }        return null;    } }


调用jni的一个类

public class Jni {    static {    System.loadLibrary("videojni");    }    public native void setSurface(Surface surface, int[] bit, int w, int h);}


jni c 的实现

#include <jni.h>#include <stdlib.h>#include "logcat.h"#include <android/native_window_jni.h>#include <android/log.h>#define LOG_TAG "System.out"#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)#define RGB_SIZE 4void _UtilsIntToBtye(unsigned char *btyeArray,int *intArray,  int len);JNIEXPORT void JNICALL Java_com_example_jni_Jni_setSurface(JNIEnv *env, jclass jazz, jobject jsurface,jintArray pixels, jint videoWidth, jint videoHeight){jsize length =(*env)->GetArrayLength(env,pixels);unsigned char btyeArr[length * 4];LOGD("pixels   length = %d",length);int* arrayPointer =(*env)->GetIntArrayElements(env,pixels,NULL);_UtilsIntToBtye(btyeArr , arrayPointer, length);ANativeWindow *mANativeWindow;mANativeWindow = ANativeWindow_fromSurface(env, jsurface);LOGD("--setSurface--form c-----1-----");// 需要先设定图像的尺寸和格式ANativeWindow_setBuffersGeometry(mANativeWindow, videoWidth, videoHeight, WINDOW_FORMAT_RGBA_8888);    ANativeWindow_Buffer nwBuffer;    if (0 != ANativeWindow_lock(mANativeWindow, &nwBuffer, NULL)) {        LOGD("ANativeWindow_lock() error");        return;    }    LOGD("--setSurface--form c-----2-----width = %d  height = %d",nwBuffer.width,nwBuffer.height);    //这里*4是因为,buffer是8位的,arrayPointer是32位,长度肯定是按8位来算    if (nwBuffer.width >= nwBuffer.stride) {        memcpy(nwBuffer.bits, btyeArr, length*4);        //  memcpy(nwBuffer.bits, arrayPointer, length*4);        LOGI("---nwBuffer.width >= nwBuffer.stride---");    } else {/*        fixed花屏问题:                      输出stride和width的日志发现,如果正常显示则stride==width,    通过注释可以看出应该是内存对齐问题导致的, 调整代码:*/        int i;        LOGI("------bits   = %d",nwBuffer.bits);        LOGI("------stride  = %d",nwBuffer.stride);       for (i = 0; i < videoHeight; i++) {       memcpy(nwBuffer.bits + nwBuffer.stride * i*RGB_SIZE,       btyeArr + videoWidth * i*RGB_SIZE, videoWidth*RGB_SIZE);        }    }    if (0 != ANativeWindow_unlockAndPost(mANativeWindow)) {    LOGD("ANativeWindow_unlockAndPost error");        return;    }    ANativeWindow_release(mANativeWindow);}void _UtilsIntToBtye(unsigned char *btyeArray,int *intArray,  int len){   int i;   LOGD("pixels   length = %d",len);   for(i = 0; i < len; i++){   //red   btyeArray[i * 4] = (unsigned char)(intArray[i] >> 16) & 0xff;   //green   btyeArray[i * 4 + 1] = (unsigned char)(intArray[i] >> 8) & 0xff;   //blue   btyeArray[i * 4 + 2] = (unsigned char)intArray[i] & 0xff;  // btyeArray[i * 4 + 3] = 0x1;   //LOGD("pixels   length = %d",len);   }   LOGD("pixels .............  length = %d",len);}

android.mk

LOCAL_PATH := $(call my-dir , common/src ,common)include $(CLEAR_VARS)LOCAL_MODULE    := videojniLOCAL_SRC_FILES := videojni.c LOCAL_LDLIBS += -llog# for loggingLOCAL_LDLIBS    += -llog# for native windowsLOCAL_LDLIBS    += -landroidinclude $(BUILD_SHARED_LIBRARY)

尊重原创,欢迎转载,转载请注明: http://blog.csdn.net/qq377366355/article/details/61519802

新手一枚,欢迎朋友指导、交流。谢谢!邮箱:zxjjiaren@qq.com



0 0
原创粉丝点击