截取 SurfaceView 的屏幕截图

新手上路,请多包涵

我正在开发一个简单的相机应用程序。我有截取整个活动的屏幕截图并将其写入 SD 卡的代码。问题是 Surfaceview 返回黑屏。

我想知道如何独立截取 surfaceview 的屏幕截图。这是获取整个活动屏幕截图的代码。

     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);
    }
}

原文由 Donnie Ibiyemi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 971
1 个回答

SurfaceView 的表面独立于绘制视图元素的表面。因此捕获视图内容不会包括 SurfaceView。

您需要单独捕获 SurfaceView 内容并执行您自己的合成步骤。进行捕获的最简单方法可能是重新渲染内容,但使用屏幕外位图作为目标而不是表面。如果您使用 GLES 渲染到屏幕外 pbuffer,则可以在交换缓冲区之前使用 glReadPixels()

更新: Grafika 的“相机纹理”活动演示了如何使用 OpenGL ES 处理来自相机的实时视频。 EglSurfaceBase#saveFrame() 显示如何捕获 GLES 渲染到位图。

更新: 另请参阅 此答案,它提供了更多背景信息。

原文由 fadden 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题