Friday 18 October 2013

Taking Screenshot of a layout in android programatically

Here is a brief explanation on how to save part of screen as an image – taking screenshot programmatically !

Example :

For Screen :

 Output :
Screenshot as image



To do this:

Step 1 : 
First identify the layout whose contents are to be saved as image and assign it to a view.
If there are lot many objects, easier is to use a frame layout

memecontentView = findViewById(R.id.frame_memecontent);
View v = memecontentView;

Step 2 :  
Manually generate a bitmap copy of the view
v1.setDrawingCacheEnabled(true);


Step 3 : For the generated bitmap, we need to set layout , else a bitmap of (0,0) will be generated and you won't be able to see it. Setting up a layout is a two pass process : a measure pass and a layout pass.

Measure Pass : For deciding dimension specifications for view
v1.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                           MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

Layout Pass :  During this pass, each parent is responsible for positioning all of its children using the sizes computed in the measure pass
v1.layout(0, 0, v1.getMeasuredWidth(), v1.getMeasuredHeight());

More Details on measure and layout pass here.

Step 4 : Force the drawing cache to be built :
v1.buildDrawingCache(true);

If we are calling this manually, we need to clean this up afterwards using destroyDrawingCache();

So this was initial preparation needed for taking the screenshot.

Step 5 : Now to take screenshot and save in sdcard :
a.) Retrieve the view to be saved using :
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
                           ByteArrayOutputStream bytes = new ByteArrayOutputStream();

b.) Compress the bitmap and use 100 as factor for maintaining the quality. If you can compromise with quality, reduce the factor
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
                           

c.) Save in sdcard
f = new File(DATA_PATH + File.separator + value);                     
  try {
   f.createNewFile();
  // write the bytes in file
  FileOutputStream fo = new FileOutputStream(f);
  fo.write(bytes.toByteArray());
  fo.close();
  }catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
  Toast.makeText(getApplicationContext(),"Image Saved at " + f.getPath(), Toast.LENGTH_SHORT).show();
                            
d.) Destroy the cache
v1.destroyDrawingCache();
                          

XML will look something like this :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:orientation="vertical"
    android:padding="2dp" >

    <RelativeLayout
        android:id="@+id/relativeLayout_titleBar"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.1"
        android:background="#4795D2" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="Screenshot App"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <ImageView
            android:id="@+id/imageView_settingsTextColor"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:src="@drawable/action_settings" />
    </RelativeLayout>

    <EditText
        android:id="@+id/editText_meme"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="5dp"
        android:layout_weight="0.1"
        android:background="@drawable/rounded_rect"
        android:hint="your text here"
        android:imeOptions="actionDone"
        android:singleLine="true" />

    <FrameLayout
        android:id="@+id/frame_memecontent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="5dp"
        android:layout_weight="0.7"
        android:background="@drawable/rounded_rect" >

        <ImageView
            android:id="@+id/frame_backgroundImage1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:src="@drawable/defaultbackground" />

        
            <ImageView
                android:id="@+id/imageview_sita"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
               android:scaleType="matrix"
                
              />
          
            <TextView
                android:id="@+id/frame_textContent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:text="Taking Screenshot"
                android:textColor="#1c86ee"
                android:textColorHint="@android:color/darker_gray"
                android:textSize="20sp"
                android:textStyle="bold" />
       
    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.1"
        android:orientation="horizontal"
        android:weightSum="2" >

        <Button
            android:id="@+id/button_changeBackgroundImage"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_margin="2dp"
            android:layout_weight="1"
            android:background="#4795D2"
            android:text="Change Background"
            android:textColor="#FFFFFF" />

       
        <Button
            android:id="@+id/button_saveImage"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_margin="2dp"
            android:layout_weight="1"
            android:background="#4795D2"
            android:text="Save / Share"
            android:textColor="#FFFFFF" />

        
        
    </LinearLayout>

</LinearLayout>


Cheers,
~Divya

No comments:

Post a Comment

Would love to hear from you. Leave a comment :)