[Android] 在Jni中对SurfaceView渲染一张图片
来源:互联网 发布:js数组赋值 编辑:程序博客网 时间:2024/06/05 23:25
ANativeWindow渲染RGB
在jni渲染图片有很多方式,比如OpenGL,这里介绍实现方式最简单的一种:直接对surface进行操作。
原理也很简单,我们直接将数据拷贝到ANativeWindow的缓存队列中,然后由系统进行处理现实到屏幕上。
- 首先创建surfaceView,只需要通过jni传入surface对象即可:
import android.content.Context;import android.util.AttributeSet;import android.view.Surface;import android.view.SurfaceHolder;import android.view.SurfaceView;public class MyVideoView extends SurfaceView implements SurfaceHolder.Callback { private OnSurfaceListener listener; private SurfaceHolder mHolder; public MyVideoView(Context context) { super(context); init(); } public MyVideoView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyVideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mHolder = this.getHolder(); mHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { setSurface(holder.getSurface()); //初始化 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { setSurface(null); //通知jni层释放surface } @Override public Surface getSurface() { SurfaceHolder holder = getHolder(); if (holder != null) { return holder.getSurface(); } return null; } }public static native void setSurface(Surface surface);
jni相关接口的实现这里不做讨论
- 接下来是在native中获取surface对象并进行初始化:
ANativeWindow *mANativeWindow = (ANativeWindow *)ANativeWindow_fromSurface(env, jsurface);// 需要先设定图像的尺寸和格式ANativeWindow_setBuffersGeometry(mANativeWindow, videoWidth, videoHeight, WINDOW_FORMAT_RGBA_8888);
mANativeWindow 既是surface在jni层的映射
- 开始进行渲染(data是传入的RGB图像数据):
ANativeWindow_Buffer nwBuffer; if (0 != ANativeWindow_lock(mANativeWindow, &nwBuffer, NULL)) { LOGE("ANativeWindow_lock() error"); return; } if (nwBuffer.width >= nwBuffer.stride) { memcpy(nwBuffer.bits, data, len); } else { /*fixed花屏问题: * 输出stride和width的日志发现,如果正常显示则stride==width, 通过注释可以看出应该是内存对齐问题导致的, 调整代码: */ int i; for (i = 0; i < height; ++i) { memcpy(nwBuffer.bits + nwBuffer.stride * i * RGB_SIZE, data + width * i * RGB_SIZE, width * RGB_SIZE); } } if (0 != ANativeWindow_unlockAndPost(player->mANativeWindow)) { LOGE("ANativeWindow_unlockAndPost error"); return; }
需要注意的是 nwBuffer.stride >= nwBuffer.width。因为nwBuffer.stride 为 POT 即2的n次方
- 完成渲染后必须对surface进行释放:
ANativeWindow_release(mANativeWindow);
参考:
http://blog.csdn.net/lsingle/article/details/38174049?utm_source=tuicool&utm_medium=referral
0 0
- [Android] 在Jni中对SurfaceView渲染一张图片
- android在jni中对SurfaceView显示一张图片
- 在SurfaceView上拖动一张小图片
- Android 对图片渲染
- Android中SurfaceView的使用详解及如何在jni(hal层)直接显示
- 在Android中的jni里使用OpenGL ES 渲染一幅图片
- 【Android】在SurfaceView上显示透明图片
- 在WPF中添加一张图片
- android从网络中获取一张图片
- Android中在SurfaceView上高效绘图
- Android中在SurfaceView上高效绘图
- Android中在SurfaceView上高效绘图
- android从网络中获得一张图片,并显示在屏幕上
- android从网络中获得一张图片,并显示在屏幕上
- android源码开发如何在framework中加入一张图片资源
- Unity中对一张2D图片进行旋转
- 在 Android 中 使用JNI
- 在JNI中对图像的处理
- 对Debug和Release的一些理解
- Codeforces 691F. Couple Cover (暴力)
- 30分钟git命令入门到放弃
- 博弈论(sg函数)
- delete 和 delete [] 区别
- [Android] 在Jni中对SurfaceView渲染一张图片
- JSTL函数标签库 fn标签
- NYOJ245编号统计
- linux 数据盘分区挂载
- 典型的非对称加密算法 RSA
- 2016 07 21
- bootstrap table分页采用server方式,分页查询
- Java NIO系列教程(三) Buffer
- 服务器硬盘的一些知识(腾讯课堂 学神教育笔记)