HOME 首页
SERVICE 服务产品
XINMEITI 新媒体代运营
CASE 服务案例
NEWS 热点资讯
ABOUT 关于我们
CONTACT 联系我们
创意岭
让品牌有温度、有情感
专注品牌策划15年

    渲染方式surfaceview和Tex

    发布时间:2023-03-12 08:39:14     稿源: 创意岭    阅读: 1021        问大家

    大家好!今天让创意岭的小编来大家介绍下关于渲染方式surfaceview和Tex的问题,以下是小编对此问题的归纳整理,让我们一起来看看吧。

    创意岭作为行业内优秀的企业,服务客户遍布全球各地,相关业务请拨打电话:175-8598-2043,或添加微信:1454722008

    本文目录:

    渲染方式surfaceview和Tex

    一、SurfaceView的简单使用

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    protected Button mBufferBtn;

    protected Button mVideoBtn;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    super.setContentView(R.layout.activity_main);

    initView();

    }

    @Override

    public void onClick(View view) {

    Intent intent = new Intent();

    if (view.getId() == R.id.button) {

    intent.setClass(this, BufferActivity.class);

    } else if (view.getId() == R.id.button) {

    intent.setClass(this, VideoActivity.class);

    }

    startActivity(intent);

    }

    private void initView() {

    mBufferBtn = (Button) findViewById(R.id.button2);

    mBufferBtn.setOnClickListener(MainActivity.this);

    mVideoBtn = (Button) findViewById(R.id.button2);

    mVideoBtn.setOnClickListener(MainActivity.this);

    }

    }

    public class BufferActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    protected SurfaceView mSurfaceView;

    private SurfaceHolder mHolder;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    super.setContentView(R.layout.activity_buffer);

    initView();

    initSurfaceHolder();

    }

    // 初始化Surface的管理者

    private void initSurfaceHolder() {

    mHolder = mSurfaceView.getHolder();

    // 添加管理生命周期的接口回调

    mHolder.addCallback(this);

    }

    private void initView() {

    mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);

    }

    // 缓冲区创建

    @Override

    public void surfaceCreated(SurfaceHolder holder) {

    Log.d("1507", "surfaceCreated");

    new DrawThread().start();

    }

    // 缓冲区内容改变(子线程渲染UI的过程)

    @Override

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    Log.d("1507", "surfaceChanged");

    }

    // 缓冲区销毁

    @Override

    public void surfaceDestroyed(SurfaceHolder holder) {

    Log.d("1507", "surfaceDestroyed");

    }

    // 绘制UI的子线程

    private class DrawThread extends Thread {

    @Override

    public void run() {

    super.run();

    // 创建画笔

    Paint paint = new Paint();

    paint.setColor(Color.GREEN);// 画笔颜色

    paint.setStrokeWidth(10);// 画笔粗细。注意:Java中设置的尺寸单位都是px

    paint.setStyle(Paint.Style.FILL_AND_STROKE);// 设置实心

    paint.setAntiAlias(true);// 设置是否抗锯齿

    // 获取SurfaceView的盖度

    int height = mSurfaceView.getHeight();

    Canvas canvas = null;

    for (int i = 0; i < height; i+= 5) {

    // 获取Surface中的画布

    canvas = mHolder.lockCanvas();// 锁定画布

    // 使用画笔在画布上绘制指定形状

    canvas.drawCircle(100, i + 50, 50, paint);// 圆心x坐标,圆心y坐标,半径,画笔

    // 缓冲区的画布绘制完毕,需要解锁并提交给窗口展示

    mHolder.unlockCanvasAndPost(canvas);

    //                try {

    //                    Thread.sleep(100);

    //                } catch (InterruptedException e) {

    //                    e.printStackTrace();

    //                }

    }

    }

    }

    }

    public class VideoActivity extends AppCompatActivity implements View.OnClickListener {

    protected MyVideoSurfaceView mSurfaceView;

    protected Button mPlayBtn;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    super.setContentView(R.layout.activity_video);

    initView();

    }

    // 运行、可见

    @Override

    protected void onStart() {

    super.onStart();

    }

    // 可交互

    @Override

    protected void onResume() {

    super.onResume();

    }

    private void play() {

    String videoPath = Environment.getExternalStorageDirectory().getPath() +

    "/VID_20171117_144736.3gp";// 外部存储根路径

    mSurfaceView.playVideo(videoPath);

    }

    private void initView() {

    mSurfaceView = (MyVideoSurfaceView) findViewById(R.id.surface_view);

    mPlayBtn = (Button) findViewById(R.id.play_btn);

    mPlayBtn.setOnClickListener(VideoActivity.this);

    }

    @Override

    public void onClick(View view) {

    if (view.getId() == R.id.play_btn) {

    play();

    }

    }

    }

    public class MyVideoSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;

    private MediaPlayer mMediaPlayer;

    public MyVideoSurfaceView(Context context, AttributeSet attrs) {

    super(context, attrs);

    init();

    }

    private void init() {

    // 获取Surface换朝哪个区的持有者

    mHolder = getHolder();

    mHolder.addCallback(this);

    }

    // 设置播放源

    public void playVideo(String path) {

    if (mMediaPlayer == null) {

    mMediaPlayer = new MediaPlayer();

    }

    try {

    // 设置播放源

    mMediaPlayer.setDataSource(path);

    // 设置多媒体的显示部分:使用SurfaceHolder渲染画面

    mMediaPlayer.setDisplay(mHolder);

    mMediaPlayer.prepare();

    mMediaPlayer.start();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    @Override

    public void surfaceCreated(SurfaceHolder holder) {

    }

    @Override

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override

    public void surfaceDestroyed(SurfaceHolder holder) {

    mMediaPlayer.release();

    mMediaPlayer = null;

    }

    }

    二、什么是surfaceview?和surface有区别吗

    SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。

    surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。

    你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。

    三、Android使用surfaceView原生绘制

    [TOC]

    ​ Activity的View hierachy的树形结构,最顶层的DecorView,也就是根结点视图,在SurfaceFlinger中有对应的Layer。

    ​ 对于具有SurfaceView的窗口来说,每一个SurfaceView在SurfaceFlinger服务中还对应有一个独立的Layer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面。

    ​ 在WMS和SurfaceFlinger中,它与宿主窗口是分离的。这样的好处是对这个Surface的渲染可以放到单独线程去做。这对于一些游戏、视频等性能相关的应用非常有益,因为它不会影响主线程对事件的响应。但它也有缺点,因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,一些View中的特性也无法使用。

    优点:

    ​ 可以在一个独立的线程中进行绘制,不会影响主线程。

    ​ 使用双缓冲机制,播放视频时画面更流畅。

    缺点:

    ​ Surface不在View hierachy中,显示也不受View的属性控制,所以不能进行平移,缩放等变换。

    ​ 在4.0(API level 14)中引入。和SurfaceView不同,不会在WMS中单独创建窗口,而是作为View hierachy中的一个普通View,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化。TextureView必须在硬件加速的窗口中。

    优点:

    ​ 支持移动、旋转、缩放等动画,支持截图

    缺点:

    ​ 必须在硬件加速的窗口中使用,占用内存比SurfaceView高(因为开启了硬件加速),可能有1〜3帧延迟。

    ​ 如果说Surface是画布(画框), SurfaceTexture则是一幅画。可以使用 new Surface(SurfaceTexture) 创建一个Surface。SurfaceTexture并不直接显示图像,而是转为一个外部纹理(图像),用于图像的二次处理。

    ​ 视频码率就是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件。码率和质量成正比,但是文件体积也和码率成正比,即 码率越高越清晰,视频文件越大 。码率率超过一定数值,对图像的质量没有多大影响,因为 原始图像只有那么清晰,再高码率也不会变的比原图更清晰 。

    ​ 每秒的帧数表示图形处理器处理场时每秒钟能够更新的次数,一般使用fps(Frames per Second)表示。因此帧率越高,画面越流畅。比如Android理论上是16ms一张图像,即60fps。

    ​ ANativeWindow代表的是本地窗口,可以看成NDK提供Native版本的Surface。通过 ANativeWindow_fromSurface 获得ANativeWindow指针, ANativeWindow_release 进行释放。类似Java,可以对它进行lock、unlockAndPost以及通过 ANativeWindow_Buffer 进行图像数据的修改。

    在NDK中使用ANativeWindow编译时需要链接NDK中的 libandroid.so 库

    四、什么是surfaceview?和surface有区别吗

    Canvas是Java层构建的数据结构,是给View用的画布。ViewGroup会把自己的Canvas拆分给子View。View会在onDraw方法里将图形数据绘制在它获得的Canvas上。

    而Surface是Native层构建的数据结构,是给SurfaceFlinger用的画布。它是直接被用来绘制到屏幕上的数据结构。

    开发者一般所用的View都是在Canvas进行绘制,然后最顶层的View(通常是DecorView)的Canvas的数据信息会转换到一个Surface上。SurfaceFlinger会将各个应用窗口的Surface进行合成,然后绘制到屏幕上(实际上是一个Buffer,但一般开发者不用考虑这些,所以省略一些概念)。

    那为什么会有一个SurfaceView呢?

    这是因为View的测量(Measure),布局(Layout)以及绘制(Draw)的计算量比较大。计算完以后再从Canvas转换成Surface中数据,然后再绘制屏幕,这个流程比较耗时。对于常规的UI绘制不会有什么问题,但是像Camera的预览以及视频的播放这样的应用场景来说就不可接受了。

    SurfaceView就是为了解决这个问题。SurfaceView内容不再是绘制在Canvas上,而是直接绘制在其持有的一个Surface上。由于省去了很多步骤,其绘制性能大大提高。而SurfaceView本身只是用来控制这个Surface的大小和位置而已。

    以上就是关于渲染方式surfaceview和Tex相关问题的回答。希望能帮到你,如有更多相关问题,您也可以联系我们的客服进行咨询,客服也会为您讲解更多精彩的知识和内容。


    推荐阅读:

    渲染和不渲染的区别图片对比(3d建模师一个月的真实收入)

    渲染设计师(渲染设计师招聘)

    学渲染的前景

    微信朋友圈投票怎么弄

    唯品奥莱和唯品自营的区别(唯品奥莱和唯品自营的区别在哪里)