Android SurfaceView 并返回包含所有绘制调用的位图



我正在使用SurfaceView,因此我可以创建一个单独的线程来绘制。我的问题是如何获取屏幕上当前像素的位图,并为其绘制到画布上。下面是一些基本概述的代码:

class SurfaceRenderView extends SurfaceView implements Runnable {
    SurfaceHolder holder;
    Thread thread;
    Canvas canvas;
    public SurfaceRenderView(Context context) {
        super(context);
        holder = getHolder(); //holder for Canvas so I can draw in my thread
        thread = new Thread(this);
        thread.start();
    }
    @Override 
    public void run() {
        // thread has started
        while(true) {
            if(holder.getSurface().isValid()) {
                canvas = holder.lockCanvas();
                // do some drawing...
                holder.unlockCanvasAndPost(canvas);
            }
        } 
    } 
}

}

因此,我想获得一个高级位图,其中包含我绘制到 SurfaceView 画布上的所有位图。因为没有方法getBitmap()可以返回整个SurfaceView的位图,所以我需要其他方法来实现这一点。请在这里帮助我。谢谢!

首先,您的示例失败了,因为 lockCanvas 仅在 UI 线程中工作,这真的很痛苦,所以我从不使用 SurfaceView。

但是,由于您坚持使用SurfaceView,因此这里有一个提示:您创建自己的位图绘制其中的所有内容,并将其提供给SurfaceHolder仅用于绘图。这就是将位图提供给应用的方式。这可能比在 SurfaceHolder 上绘制效率低,因为在这种情况下图形加速不起作用。

该示例假定线程在图面准备就绪初始化,因此您知道视图的宽度和大小。(你可能应该使用AsyncTask而不是Thread,但我相当老式:)

public class DrawingThread extends Thread  {
     Activity activity;
     SurfaceView view;;
     Bitmap backBuffer;
     boolean bufferProcessed;
     public DrawingThread(Activity activity, SurfaceView view) {
          this.activity = activity;
          this.view = view;
          backBuffer = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888);          
     }
     @Override
     public void run() {
          try {
               for (;;) {
                   Canvas canv = new Canvas(backBuffer);
                   // Draw on canvas  
                   .....................................  
                   bufferProcessed = false;
                   activity.runOnUiThread(new Runnable() {
                       public void run() {
                          SurfaceHolder holder = view.getHolder();
                          Canvas hCanv = holder.lockCanvas();
                          hCanv.drawBitmap(backBuffer, 0f, 0f, null);
                          holder.unlockCanvasAndPost(hCanv);
                          synchronized(DrawingThread.this) {
                               bufferProcessed = true;
                               DrawingThread.this.notify(); 
                          }
                       }
                   });  
                   while(!bufferProcessed) 
                      synchronized(this) {wait();}
               }
           }catch(InterruptedException ex) {}

     }

}

最新更新