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?
Related
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;
}
my problem is similar to How to get all children (visible and invisible) from a ListView?
i need to save all listview items to bitmap, listview item is inflated by textview. whatever they are visible or invisible in the lisview.
i want to get all child views and convert to bitmap, i tried as below:
view = adapter.getView(i,null,lv);
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth()
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
bitmap.eraseColor(Color.WHITE);
Canvas canvas = new Canvas(bitmap);
canvas.translate(10, 10);
view.draw(canvas);
mybitmap = combineImages(mybitmap, bitmap);
but if item text is too much (some of them contain long text) the methods ,view.getMeasuredWidth() and view.getMeasuredHeight(), which are not working properly.
I`m wondering if my idea to this problem is right , if not , how can I solve it ?
Used the following to fix:
view.measure(MeasureSpec.makeMeasureSpec(lv.getWidth(),
MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED));
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.
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);
I want to send graphs in email. So for that I have captured bitmap of that graph and save it in sdcard as image. that works successfully
private Bitmap TakeImage(View v) {
Bitmap screen = null;
try {
v.setDrawingCacheEnabled(true);
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
screen = v.getDrawingCache();
v.setDrawingCacheEnabled(false); // clear drawing cache
} catch (Exception e) {
e.printStackTrace();
}
return screen;
}
But now I want to capture that in background without showing that layout, without notify by user. My previous code does not work for that.
Inflate the view using LayoutInflater, populate the values and pass it on to the same takeImage(View v) method.
I'm not sure, and I've not tried, don't know whether this works or not. but give it a try.
Have you tried changing v.getMeasuredWidth(), v.getMeasuredHeight() to whatever values you desire?
can you use
view.getLocationOnScreen(l);