以SurfaceView的屏幕截图截图、屏幕、SurfaceView

2023-09-12 21:38:42 作者:动不动就胖了

正在开发一个简单的摄像头应用程序。我有code,是以整个活动的截图并将其写入到SD卡上。的问题是,Surfaceview返回黑屏。

我想知道如何独立只拿surfaceview的屏幕截图。 这里是code,是以整个活动的截图。

  findViewById(R.id.screen).setOnClickListener(新OnClickListener(){
      @覆盖
     公共无效的onClick(视图v){
     最后RelativeLayout的布局=(RelativeLayout的)findViewById(R.id.RelativeLayout1);
      layout.setVisibility(RelativeLayout.GONE);
       点阵位图= takeScreenshot();
        Toast.makeText(getApplicationContext(),请等待,Toast.LENGTH_LONG).show();
       saveBitmap(位);
   }
});

}



      公共位图takeScreenshot(){
       查看rootView = findViewById(android.R.id.content).getRootView();
       rootView.setDrawingCacheEnabled(真正的);
       返回rootView.getDrawingCache();
    }


           公共无效saveBitmap(位图位图){
         最后MediaPlayer的欢呼= MediaPlayer.create(PicShot.this,R.raw.shutter);
       cheer.start();
        随机数发生器=新的随机();
      INT N = 10000;
       N = generator.nextInt(N);
        字符串FNAME =图像 - + N +巴。
      最后RelativeLayout的布局=(RelativeLayout的)findViewById(R.id.RelativeLayout1);
     文件的ImagePath =新的文件(Environment.getExternalStorageDirectory()+/+ FNAME);
     FileOutputStream中FOS;
      尝试 {
        FOS =新的FileOutputStream(的ImagePath);
        bitmap.com preSS(比较pressFormat.PNG,100,FOS);
        fos.flush();
        fos.close();
        layout.setVisibility(RelativeLayout.VISIBLE);
        意图份额=新的意图(Intent.ACTION_SEND);
        share.setType(图像/ *);
        开放的我们的uri = Uri.fromFile(的ImagePath);
        share.putExtra(Intent.EXTRA_STREAM,URI);
        startActivity(Intent.createChooser(份额,共享图片));
    }赶上(FileNotFoundException异常E){
        Log.e(GREC,e.getMessage(),E);
    }赶上(IOException异常E){
        Log.e(GREC,e.getMessage(),E);
    }
}
 

解决方案

在SurfaceView的表面是独立于表面上视图元素绘制的。因此,捕捉查看内容将不包括SurfaceView。

您需要单独捕获SurfaceView内容和执行自己的合成步骤。做捕获的最简单的方法可能是刚刚重新呈现的内容,而是用一个离屏位图作为目标,而不是表面。如果你正在渲染与GLES到离屏幕的pbuffer,您可以使用 glReadPixels()你交换缓冲之前。

更新: Grafika的纹理的相机活动演示了处理视频直播从相机的OpenGL ES。 EglSurfaceBase#saveFrame()显示了如何捕捉GLES渲染为位图。

更新:参见这个答案,它提供了更多的背景。

真的存在过 Surface Mini屏幕组件曝光

Am developing a simple camera app. I have code that takes screenshot of the whole activity and writes it to the Sd card. the problem is that the Surfaceview returns a black screen.

I would like to know how to independently take a screenshot of the surfaceview only. here is the code that takes the screenshot of the Whole activity.

    findViewById(R.id.screen).setOnClickListener(new OnClickListener() {
      @Override
     public void onClick(View v) {
     final RelativeLayout layout = (RelativeLayout) findViewById(R.id.RelativeLayout1);
      layout.setVisibility(RelativeLayout.GONE);
       Bitmap bitmap = takeScreenshot();
        Toast.makeText(getApplicationContext(),"Please Wait",         Toast.LENGTH_LONG).show();
       saveBitmap(bitmap);
   }
});

}



      public Bitmap takeScreenshot() {
       View rootView = findViewById(android.R.id.content).getRootView();
       rootView.setDrawingCacheEnabled(true);
       return rootView.getDrawingCache();
    }


           public void saveBitmap(Bitmap bitmap) {
         final MediaPlayer cheer = MediaPlayer.create(PicShot.this, R.raw.shutter);
       cheer.start();
        Random generator = new Random();
      int n = 10000;
       n = generator.nextInt(n);
        String fname = "Image-"+ n +".png";
      final RelativeLayout layout = (RelativeLayout)     findViewById(R.id.RelativeLayout1);
     File imagePath = new File(Environment.getExternalStorageDirectory() + "/" + fname);
     FileOutputStream fos;
      try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
        layout.setVisibility(RelativeLayout.VISIBLE);
        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("image/*");
        Uri uri = Uri.fromFile(imagePath);
        share.putExtra(Intent.EXTRA_STREAM,uri);
        startActivity(Intent.createChooser(share, "Share Image"));
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

解决方案

The SurfaceView's surface is independent of the surface on which View elements are drawn. So capturing the View contents won't include the SurfaceView.

You need to capture the SurfaceView contents separately and perform your own composition step. The easiest way to do the capture is probably to just re-render the contents, but use an off-screen bitmap as the target rather than the surface. If you're rendering with GLES to an off-screen pbuffer, you can use glReadPixels() before you swap buffers.

Update: Grafika's "texture from camera" activity demonstrates handling live video from the camera with OpenGL ES. EglSurfaceBase#saveFrame() shows how to capture GLES rendering to a Bitmap.

Update: See also this answer, which provides a bit more background.