Monday, 11 February 2013

Capture Screen Programatically In Android



Before Screen capture the screen looks something like this : 


After Screen capture the screen shows the preview as :






package com.mayursharma.example.capture.screen;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

public class MainActivity extends Activity {
    
 ImageView imageViewCapture, imageViewPreview;
 Bitmap bitmap;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        imageViewPreview = (ImageView) findViewById(R.id.ImageViewPreview);
        imageViewCapture = (ImageView) findViewById(R.id.ImageViewCapture);
        imageViewCapture.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    bitmap = getBitmapOfView(imageViewCapture); 
    imageViewPreview.setImageBitmap(bitmap);
    createImageFromBitmap(bitmap);
   }
  });
 
    }//onCreate Ends
    
    
    /*
     * @author : Mayur Sharma
     * This method is used to create the bitmap of the current activity
     * This method accepts any child view of the current view
     * You can even pass the parent container like RelativeLayout or LinearLayout as a param
     * @param : View v
     */
    public Bitmap getBitmapOfView(View v)
    {
        View rootview = v.getRootView();
     rootview.setDrawingCacheEnabled(true);
     Bitmap bmp = rootview.getDrawingCache();
     return bmp;
    }
    
    
    /*
     * @author : Mayur Sharma
     * This method is used to create an image file using the bitmap
     * This method accepts an object of Bitmap class
     * Currently we are passing the bitmap of the root view of current activity
     * The image file will be created by the name capturedscreen.jpg
     * @param : Bitmap bmp
     */
    public void createImageFromBitmap(Bitmap bmp)
    {
     ByteArrayOutputStream bytes = new ByteArrayOutputStream();
  bmp.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
  File file = new File( Environment.getExternalStorageDirectory() +
                                           "/capturedscreen.jpg");
  try 
  {
   file.createNewFile();
   FileOutputStream ostream = new FileOutputStream(file);
   ostream.write(bytes.toByteArray());        
   ostream.close();
  } 
  catch (Exception e) 
  {
   e.printStackTrace();
  }    
    }
    
    
}//Class Ends


Create a new xml file in res/drawable folder so as to use it as a border for Preview ImageView.
Put the below source code in the xml file and save it by name "pic_preview_border.xml"
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:dither="true">
    <gradient
         android:startColor="#99ffffff"
         android:endColor="#99ffffff"
         android:centerColor="#00000000"
         android:angle="90" />
    
    <padding android:left="10dp" android:top="10dp"
            android:right="10dp" android:bottom="10dp" />
    <corners android:radius="5dp" />
    <stroke
        android:width="2dp"
        android:color="#ccffffff"
        />
</shape>


Create a new XML file in the res/layout folder as "main.xml" which will be used as a layout for the above mentioned activity. Put the below code in the main.xml file.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="#0080AA">

 <TextView 
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" 
  android:text="@string/hello" />

 <TextView 
  android:layout_width="fill_parent"
  android:layout_above="@+id/ImageViewPreview" 
  android:layout_height="wrap_content"
  android:text="Preview : " />

 <ImageView 
  android:layout_width="200dp"
  android:layout_height="250dp" 
  android:adjustViewBounds="true"
  android:scaleType="fitXY" 
  android:layout_centerInParent="true"
  android:id="@+id/ImageViewPreview" 
  android:src="@drawable/user_pic"
  android:background="@drawable/pic_preview_border" />

 <ImageView android:layout_width="130dp"
  android:layout_height="50dp" 
  android:adjustViewBounds="true"
  android:scaleType="fitXY" 
  android:layout_marginBottom="3dp"
  android:src="@drawable/capture" 
  android:id="@+id/ImageViewCapture"
  android:layout_alignParentBottom="true"
  android:layout_centerHorizontal="true" />

</RelativeLayout>



Click HERE to Download Complete Source Code.
Click HERE to download the apk.

22 comments:

  1. hi Mayur
    It is really useful blog.I liked it very much.It helps me to integrate in my project.thanks

    ReplyDelete
  2. Helped a lot. Totaly working code which solved my problems.
    Looking forward for such unique ideas.

    ReplyDelete
  3. Helped a lot. Totaly working code which solved my problems.
    Looking forward for such unique ideas.

    ReplyDelete
  4. thanxxx...its realy useful in my application

    ReplyDelete
  5. nice work.....keep it up....

    ReplyDelete
  6. yaap .....that's nice one

    ReplyDelete
  7. Hi Mayur,
    Nice to know people can still put great working code on the 'net. I just needed a simple grab the current parent view screenshot and save to a dynamic filename. This did the trick.
    I consolidated your code a little for my purposes and added a return to
    fRet = bmp.compress(Bitmap.CompressFormat.JPEG, 30, bytes);
    ... so I could check the return value.

    Thanks!

    ReplyDelete

  8. Camera is such a very nice technology for now its very good idea
    to write an article like yours that was very good i have a
    android phone online store
    i need to write some blogs so i can boost my sales in my online
    store atleast i have a idea now thanks for you.

    ReplyDelete
  9. dude its nice code thank you.....
    but the image is not showing in external storage
    can u tell me ....

    ReplyDelete
  10. Excellent. Thanx man. Helped a lot.

    ReplyDelete
  11. Thanks for the post, but is it possible to capture the screen itself not my application.
    Lets say I have a service running in background and I want to capture the screen and do some processing of the image (store it to a file, compare it to an other image....)
    Is that possible?

    ReplyDelete
  12. Using the codes you gave is giving a black (blank) activity screen as the bitmap image. What can be the problem?
    Thanks.

    ReplyDelete
  13. thanks! how do I save it in the device's gallery?

    ReplyDelete
  14. How can i take screen shot of surfaceview vido

    ReplyDelete
  15. How can i take screen shot of surfaceview vido

    ReplyDelete
  16. Fine,But cant take image of surfceView.it will result a blackscreen image only... :(

    ReplyDelete
  17. a dont get the image in sdcard

    ReplyDelete
  18. i am unable to get the image in sdcard

    ReplyDelete