Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Bitmap from oversized view

PROBLEM DESCRIPTION:
I have tested the following two methods, in order to create a bitmap snaphot from a View (e.g. a RelativeLayout in this case). Both methods work excellent for Views which dimensions (e.g. width and height) are less than the dimensions of the device screen (e.g. 480x900). The visible part of the View is captured and written into the bitmap. Unfortunately, the bitmap is black in the unvisible part of the View.

QUESTION:
How can I capture also the unvisible part of the View ?

CODE:

public class NewRelativeLayout extends RelativeLayout{

private Bitmap bmp;

public NewRelativeLayout(Context context){
    super(context);
    this.setLayoutParams(new RelativeLayout.LayoutParams(2000,2000));
    // add here methods to configure the RelativeLayout or to add children
    }

//This is the first method
public void makeSnapshot_Method1(){
    this.setDrawingCacheEnabled(true);   
    bmp = Bitmap.createBitmap(this.getDrawingCache());   
    this.setDrawingCacheEnabled(false);
    }

//This is the second method
public void makeSnapshot_Method2(){
    bmp = Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888);
    Canvas helpCanvas = new Canvas(bmp);
    this.draw(helpCanvas);
    }

}

like image 814
Anne Droid Avatar asked Feb 15 '12 16:02

Anne Droid


People also ask

How do I reduce the size of a bitmap?

JPEG compression can significantly reduce bitmap image file size, but can result in the loss of fine detail for some images.

How do you handle bitmap in Android as it takes too much memory?

Choose the most appropriate decode method based on your image data source. These methods attempt to allocate memory for the constructed bitmap and therefore can easily result in an OutOfMemory exception. Each type of decode method has additional signatures that let you specify decoding options via the BitmapFactory.

How do I find the size of a bitmap?

File size can be expressed as the resolution (the image width multiplied by the image height) multiplied by the bit depth (the number of bits needed to store colours).

How do I check image size on android?

On android go to photos, select your photo and click the ... in the top right. Scroll to bottom of page to find image size.


1 Answers

I was searching for the solution to this too and, in the end, managed to come up with my own solution which is actually quite simple.

In my case, I had a LinearLayout which contained a number of View elements, some of which sometimes were not on screen, vertically below the end of the screen bounds. I was able to save the View as a Bitmap (see loadBitmapFromView(), below) but had trouble when it extended beyond the bottom of the screen.

My solution was to make the LinearLayout part of a ScrollView composite.

e.g.

This:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_linear_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
 >
<!-- Some Views added here at runtime -->
</LinearLayout>

Became:

Note use of wrap_content to ensure ScrollView scales to the height of your content.

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    >

    <LinearLayout
        android:id="@+id/my_linear_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
     >
        <!-- Some Views added here at runtime -->
    </LinearLayout>
</ScrollView>

This seemed to ensure that the offscreen items could be manually laid out when I wanted to save the View as a bitmap. I used the following method to save the bitmap. I found this much earlier on SO but I can't seem to find the question in order to reference it properly (whoever you are - thank you!).

For the following method, I pass in a reference to the LinearLayout above (my_linear_layout).

public static Bitmap loadBitmapFromView(View view) {
    Bitmap bitmap = null;

    // width measure spec
    int widthSpec = View.MeasureSpec.makeMeasureSpec(
            view.getMeasuredWidth(), View.MeasureSpec.AT_MOST);
    // height measure spec
    int heightSpec = View.MeasureSpec.makeMeasureSpec(
            view.getMeasuredHeight(), View.MeasureSpec.AT_MOST);

    // measure the view
    view.measure(widthSpec, heightSpec);

    // set the layout sizes
    int left = view.getLeft();
    int top = view.getTop();
    int width = view.getMeasuredWidth();
    int height = view.getMeasuredHeight();
    int scrollX = view.getScrollX();
    int scrollY = view.getScrollY();

    view.layout(left, top, width + left, height + top);

    // create the bitmap

    bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
            Bitmap.Config.ARGB_8888);

    // create a canvas used to get the view's image and draw it on the
    // bitmap

    Canvas c = new Canvas(bitmap);
    // position the image inside the canvas
    c.translate(-view.getScrollX(), -view.getScrollY());
    // get the canvas
    view.draw(c);

    return bitmap;
}
like image 54
aoemerson Avatar answered Oct 05 '22 16:10

aoemerson