Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take a screenshot of Android's Surface View?

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.

like image 760
Tariq Mahmood Avatar asked Jan 31 '13 06:01

Tariq Mahmood


People also ask

How do I take a screenshot on Android manually?

Use the Android Screenshot ShortcutPress and hold the Power + Volume Down buttons at the same time, and you'll see a brief onscreen animation followed by a confirmation in the notification bar that the action was successful.

How do I take a screenshot of an object?

Press the Volume Down rocker and the Power button at the same time. Note: Some Android devices may have different button combinations or require an app to take a screenshot. Hold the buttons until the screenshot is taken. Preview your screenshot in your gallery.


2 Answers

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.
like image 68
harikrishnan Avatar answered Oct 17 '22 00:10

harikrishnan


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

like image 45
Kirill Vashilo Avatar answered Oct 16 '22 22:10

Kirill Vashilo