繁体   English   中英

带有OpenGL的Android屏幕截图

[英]Android screenshot with OpenGL

我想用Android OpenGL截屏。.我在这里找到了一些代码,花了几天时间尝试将其放置到位,但是由于我是OpenGL和Android的新手,我想我缺少了一些东西。代码中没有错误,但应用程序一旦启动就会崩溃。

MainActivity.java

public class MainActivity extends Activity {

private GLSurfaceView ourSurface;
public static int x=0,y=0;
public static int w;
public static int h;
public static int bt[]=new int[w*h];

 // Call back when the activity is started, to initialize the view
   @Override
 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ourSurface = new GLSurfaceView(this);       // Allocate a GLSurfaceView
        ourSurface.setRenderer(new GLRenderer(this));   // Use a custom renderer
        setContentView(ourSurface); // This activity sets to GLSurfaceView


        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int h = metrics.heightPixels;
        int w = metrics.widthPixels;
 }

// Call back when the activity is going into the background
@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    ourSurface.onPause();
}


// Call back after onPause()
@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    ourSurface.onResume();
}
}

GLRenderer.java

public class GLRenderer implements Renderer{
   Context context;   // Application's context

public GLRenderer(Context context) {
          this.context = context;
}


@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
      // TODO Auto-generated method stub
      gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  // Set color's clear-value to black
      gl.glClearDepthf(1.0f);            // Set depth's clear-value to farthest
      gl.glEnable(GL10.GL_DEPTH_TEST); //Enables depth-buffer for hidden surface removal
      gl.glDepthFunc(GL10.GL_LEQUAL);    // The type of depth testing to do
          gl.glShadeModel(GL10.GL_SMOOTH);   // Enable smooth shading of color
      gl.glDisable(GL10.GL_DITHER);     // Disable dithering for better performance
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub
    }

@Override
public void onDrawFrame(GL10 gl) {
    // TODO Auto-generated method stub
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
     Shooting.savePixelsOnScreen(0, 0, MainActivity.w, MainActivity.h, gl);
}
}

Shooting.java

public class Shooting extends GLSurfaceView {
GLRenderer glRenderer; 
    public Shooting(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    //glRenderer = new GLRenderer();
    setRenderer(glRenderer);
}
 public static Bitmap savePixelsOnScreen(int x, int y, int width, int height, GL10 gl)
{
      int b[]=new int[MainActivity.w*(y + MainActivity.h)];
      IntBuffer ib=IntBuffer.wrap(b);
      ib.position(0);
      gl.glReadPixels(x, 0, MainActivity.w, y+MainActivity.h, GL10.GL_RGBA,GL10.GL_UNSIGNED_BYTE, ib);

for(int i=0, k=0; i<MainActivity.h; i++, k++)
{//OpenGL bitmap is incompatible with Android bitmap and so, some correction need.
  for(int j=0; j<MainActivity.w; j++)
      {
           int pix=b[i*MainActivity.w+j];
           int pb=(pix>>16)&0xff;
           int pr=(pix<<16)&0x00ff0000;
           int pix1=(pix&0xff00ff00) | pr | pb;
           MainActivity.bt[(MainActivity.h-k-1)*MainActivity.w+j]=pix1;
      }
 }
return bmp;
    }

static Bitmap bmp = Bitmap.createBitmap(MainActivity.bt, MainActivity.w,MainActivity.h,Bitmap.Config.ARGB_8888); {

    try
   {
    File f = new File(Environment.getExternalStorageDirectory().getPath() + "testpicture.png");
           f.createNewFile();
           FileOutputStream fos=new FileOutputStream(f);
           bmp.compress(CompressFormat.PNG, 100, fos);
     try
           {
           fos.flush();
           }
     catch (IOException e)
           {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
           }
      try
           {
                   fos.close();
           }
      catch (IOException e)
           {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
           }
   }
      catch (FileNotFoundException e)
   {
                // TODO Auto-generated catch block
                e.printStackTrace();
   }
      catch(IOException e)
   {
                e.printStackTrace();
   }
   }
   EGL10 egl = (EGL10)EGLContext.getEGL();
   GL10 gl = (GL10)egl.eglGetCurrentContext().getGL();
   }

您的主要问题在这里:

public static int w;
public static int h;
public static int bt[]=new int[w*h];

wh默认情况下初始化为0,因此您将bt分配为大小为0的数组。在onCreate更改wh的值不会自动重新分配bt数组。

可能还有一些正确性问题。 例如,我认为将整数分解为RGB分量的方式不正确。 使用ByteBuffer代替IntBuffer读回结果可能会更容易。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM