How to take a screenshot of Android's Surface

2019-01-26 08:06发布

I want to programatically take screen shot of my game, just as you'd get in Eclipse DDMS.

Screenshot taken through the solution proposed here: How to programmatically take a screenshot in Android? and in most other SO questions only have View elements visible, but not the SurfaceView.

SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get root view
View view = activity.getWindow().getDecorView().getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);

// Get current theme to know which background to use
final Theme theme = activity.getTheme();
final TypedArray ta = theme
    .obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);

// Draw background
background.draw(canvas);

// Draw views
view.draw(canvas);

// Save the screenshot to the file system
FileOutputStream fos = null;
try {
    final File sddir = new File(SCREENSHOTS_LOCATIONS);
    if (!sddir.exists()) {
        sddir.mkdirs();
    }
    fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
            + System.currentTimeMillis() + ".jpg");
    if (fos != null) {
        if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
            Log.d("ScreenShot", "Compress/Write failed");
        }
        fos.flush();
        fos.close();
    }

} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Any help in this regard would be highly appreciated. Thanks.

2条回答
迷人小祖宗
2楼-- · 2019-01-26 08:32

I hope this also useful for you. here little difference for the above answer is for I used glsurfaceview to take the screen shots hen i click the button. this image is stored in sdcard for mentioned folder : sdcard/emulated/0/printerscreenshots/image/...images

 My Program :

 View view_storelayout ;
 view_storelayout = findViewById(R.id.gl_surface_view);

   button onclick() {

   view_storelayout.setDrawingCacheEnabled(true); 

view_storelayout.buildDrawingCache(true);

Bitmap bmp = Bitmap.createBitmap(view_storelayout.getDrawingCache());
view_storelayout.setDrawingCacheEnabled(false); // clear drawing cache
                ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
                bmp.compress(CompressFormat.JPEG, 90, bos); 
                byte[] bitmapdata = bos.toByteArray();
                ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);

                final Calendar c=Calendar.getInstance();
                 long mytimestamp=c.getTimeInMillis();
                String timeStamp=String.valueOf(mytimestamp);
                String myfile="hari"+timeStamp+".jpeg";

 dir_image=new  File(Environment.getExternalStorageDirectory()+
      File.separator+"printerscreenshots"+File.separator+"image");
                dir_image.mkdirs();

                try {
                    File tmpFile = new File(dir_image,myfile); 
                    FileOutputStream fos = new FileOutputStream(tmpFile);

                     byte[] buf = new byte[1024];
                        int len;
                        while ((len = fis.read(buf)) > 0) {
                            fos.write(buf, 0, len);
                        }
                            fis.close();
                            fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

     Toast.makeText(getApplicationContext(), "myPath:"
            +dir_image.toString(), Toast.LENGTH_SHORT).show();
                Log.v("hari", "screenshots:"+dir_image.toString());

  }

 Note :
          But, here i am faced one problem. In this surfaceview , i drawn line and circle
  at runtime. after drawn some objects, when i take screenshots , its stored only for
  black image like surfaceview is stored as an image.

 And also i want to store that surfaceview image as an .dxf format(autocad format).
 i tried to stored image file as an .dxf file format.its saved successfully in 
 autocad format. but, it cant open in autocad software to edit my .dxf file.
查看更多
SAY GOODBYE
3楼-- · 2019-01-26 08:41

The code from the Usman Kurd answer will not work is most cases.

Unless you're rendering H.264 video frames in software with Canvas onto a View, the drawing-cache approach won't work (see e.g. this answer).

You cannot read pixels from the Surface part of the SurfaceView. The basic problem is that a Surface is a queue of buffers with a producer-consumer interface, and your app is on the producer side. The consumer, usually the system compositor (SurfaceFlinger), is able to capture a screen shot because it's on the other end of the pipe.

Take Screenshot of SurfaceView

查看更多
登录 后发表回答