I have wrote a method to convert any layout Liner,Relative,Frame etc into Bitmap but I want to make this method generic so that it accepts android.view.ViewGroup as a parameter rather than specific Relative or LinearLayout.
Here is my method below:
public Bitmap getBitmapFromView(RelativeLayout v) {
v.setLayoutParams(new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Both Layout's inherit from ViewGroup, so you can use ViewGroup as method parameter and all those statements will works fine.
Also you should use ViewGroup.LayoutParams instead of RelativeLayout.LayoutParams to make it generic.
Related
I tried the following code to convert the LinearLayout to image:
public static Bitmap loadBitmapFromView(View v) {
v.measure(
View.MeasureSpec.makeMeasureSpec(v.getLayoutParams().width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight()
, Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
but I have this exception
java.lang.IllegalArgumentException: bitmap size exceeds 32 bits
How I can solve this problem?
Use Bitmap.Config.ARGB_8888 and make sure the resolved width and height are not 0.
Alternatively you can also use getDrawingCache
view.setDrawingCacheEnabled(true);
view.buildDrawingCache(true);
Bitmap bitmap = view.getDrawingCache();
Try this:
private Bitmap generateBitmap(LinearLayout view)
{
//Provide it with a layout params. It should necessarily be wrapping the
//content as we not really going to have a parent for it.
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
//Pre-measure the view so that height and width don't remain null.
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
//Assign a size and position to the view and all of its descendants
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
//Create the bitmap
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
//Create a canvas with the specified bitmap to draw into
Canvas c = new Canvas(bitmap);
//Render this view (and all of its children) to the given Canvas
view.draw(c);
return bitmap;
}
public static Bitmap loadBitmapFromView(View view) {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
return view.getDrawingCache();
}
Try this code to get Bitmap from LinearLayout in Android:
public static Bitmap CreateBitmap(View layout) {
layout.setDrawingCacheEnabled(true);
layout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
layout.layout(0, 0, layout.getMeasuredWidth(), layout.getMeasuredHeight());
layout.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(layout.getWidth(), layout.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
layout.draw(canvas);
return bitmap;
}
Here is the code for convert view to bitmap.
public static Bitmap loadBitmapFromView(View v) {
v.measure(View.MeasureSpec.makeMeasureSpec(v.getLayoutParams().width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Above code create real size bitmap properly. But all child position is not scaling with layout ratio.
In my code, I have a LinearLayout with many TextViews (like a table). And I try to convert this to Bitmap. there is my code:
public static Bitmap convertToBitmap(LinearLayout view){
view.measure(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
view.draw(c);
return bitmap;
}
But, there is a problem.
Views witch has setSingleLine(true) not display text in bitmap.
Exactly, the problem is in setHorizontallyScrolling(true), which is calling in setSingleLine code...
I try use .setScrollTo(X), but what exactly X must be. X = 0 - not works.
Is there any, who knows how fix it?
EDIT: TextViews has fixed Width.
EDIT: Problem is only for TextViews with Gravity = Center. With gravity Left all's ok.
Try one of this code? It's a bit different from the one you posted above.
/**
* this actually also provided by Romain Guy, but let's try another for performance improvements
*/
public static Bitmap getBitmapFromView(View view, int width, int height) {
view.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
// Build the Drawing Cache
view.buildDrawingCache();
// Create Bitmap
Bitmap drawingCache = view.getDrawingCache();
if (drawingCache == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(drawingCache);
drawingCache.recycle();
view.setDrawingCacheEnabled(false);
return bitmap;
}
/**
* This method provided by Romain Guy, so it should do the job better, especially it includes case for listViews
*/
public static Bitmap getBitmapFromView(View view, int width, int height) {
//Pre-measure the view so that height and width don't remain null.
view.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
//Assign a size and position to the view and all of its descendants
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
// Create bitmap
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565);
//Create a canvas with the specified bitmap to draw into
Canvas canvas = new Canvas(bitmap);
// if it's scrollView we get gull size
canvas.translate(-view.getScrollX(), -view.getScrollY());
//Render this view (and all of its children) to the given Canvas
view.draw(canvas);
return bitmap;
}
I tried various methods after googling for hours. Some of the methods seem to help some people, but not for me. What am I missing here? Maybe a permission? I know this is a common bug or something, but there must be a solution.
All the methods are similar.
First:
GraphicalView v = ChartFactory.getBarChartView(ChartsDuration.this, buildBarDataset(titles, values), renderer, Type.DEFAULT);
v.setDrawingCacheEnabled(true);
v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
v.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(v.toBitmap()); //bitmap is null
v.setDrawingCacheEnabled(false);
or this:
Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache()); //bitmap is null
I also tried the solution here which is:
v.setDrawingCacheEnabled(true);
// this is the important code :)
// Without it the view will have a dimension of 0,0 and the bitmap will be null
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
Then the method on the bottom of this page:
v.setDrawingCacheEnabled(false);
if (!v.isDrawingCacheEnabled()) {
v.setDrawingCacheEnabled(true);
}
if (renderer.isApplyBackgroundColor()) {
v.setDrawingCacheBackgroundColor(renderer.getBackgroundColor());
}
v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
v.getDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
I also did not get any luck with this:
v.setDrawingCacheEnabled(true);
v.requestFocus();
v.getRootView();
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
Bitmap mBitmap = v.getDrawingCache();
The bitmaps are always null.
just an idea , not sure if it would work:
put the Achartengine view in another view (a frameLayout , for example) , and then capture it instead of the Achartengine view.
also , sure your code runs only after some time , that all of the views have drawn themselves? in order to check it , try getting the width or height of the view.
you also don't have any exceptions or special logs?
I am creating the bitmap from a linearlayout with the following code
public static Bitmap loadBitmapFromView(View v ) {
//Bitmap b = Bitmap.createBitmap( v.getLayoutParams.width, v.getLayoutParams.height, Bitmap.Config.ARGB_8888);
Bitmap b = Bitmap.createBitmap( v.getLayoutParams.width, v.getLayoutParams.height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.draw(c);
return b;
}
but i can not see the views in it
all i can see is a big grey screen
have tried the answer at this question also Android Problems Converting ViewGroup with Children into Bitmap but still not working
My view is being inflated from xml
and when i use the code mentioned above i get force close for null pointer exception
and if i mention the width and height to some number like 200 , 200 then i am able to see the grey background only not the view in it.
You need to measure the view before layout like
v.measure(
MeasureSpec.makeMeasureSpec(v.getLayoutParams().width,MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight()
,Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);