4

I am trying to create a bitmap from a View that is not displayed yet to set it as a texture with OpenGL in android. The problem is that when I create my bitmap the layout parameters of my View have 0 value cause the onLayout() function has not been called yet. Is there a way to "simulate" a layout or do a "background layout" to get the right layout params ? I was thinking about a Frame layout having two views, the background one would be used to create my bitmap as the layout would have been done.

Thanks.

candiru
  • 4,424
  • 2
  • 22
  • 16
dMathieuD
  • 113
  • 1
  • 10

2 Answers2

20

You indeed need to layout your View before drawing it into a Bitmap. Simply call myView.measure(...);

then

myView.layout(0, 0, myView.getMeasuredWidth(), myView.getMeasuredHeight());

I have posted an example on how to do this in one of the following presentations: http://www.curious-creature.org/2010/12/02/android-graphics-animations-and-tips-tricks/

DiscDev
  • 38,652
  • 20
  • 117
  • 133
Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • 3
    Thanks Romain I tried your solution. It's working well. I post it here for those who wouldn't like to parse the presentation (which contain very useful information): – dMathieuD Dec 06 '10 at 10:50
  • 3
    int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNDEFINED); view.measure(spec, spec); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); Bitmap b = Bitmap.createBitmap( view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); c.translate(-view.getScrollX(), -view.getScrollY()); view.draw(c); – dMathieuD Dec 06 '10 at 10:53
  • This works awesome! You can use the layout parameters in order to figure out what size your bitmap needs to be with this. – Codeman Aug 18 '11 at 21:15
1

So, some edits after the question was clarified :)

I suggest you create the bitmap independently of the view, then scale it to the same size as the view once the view is created. Create an arbitrary size bitmap that allows you to render what you want to it ..

// This in some class that renders your bitmap independently, and can be
// queried to get the bitmap ...
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444); 
// render something to your bitmap here

Then after your view is created, take the precreated bitmap and rescale it to the right size (I've not actually checked this by compiling it -- might be errors):

Rect original = new Rect(0, 0, 100, 100);
RectF destination = new RectF(0.0, 0.0, (float)myView.getWidth(), (float)myView.getHeight());
Canvas canvas = new Canvas(); 
canvas.drawBitmap(myRenderingClass.b, original, destination, null); 
myView.draw(canvas);
Tim Barrass
  • 4,813
  • 2
  • 29
  • 55
  • Ok maybe I was not clear enough. Forget about openGL. Let say I want a bitmap from my View that has not been displayed yet. Is there a way to achieve it ? – dMathieuD Dec 03 '10 at 15:45
  • Hm. It sounds like you might want to separate the bitmap rendering from the view (by refactoring the bitmap creation code into a new class) and make the bitmap available from that new rendering class instead. Then you'll have more control over the rendering process. – Tim Barrass Dec 03 '10 at 15:49
  • Ok so if I want to follow this way of creating my bitmap: – dMathieuD Dec 03 '10 at 16:02
  • Bitmap b = Bitmap.createBitmap(myView.getWidth(), myView.getHeight(), Bitmap.Config.ARGB_4444); Canvas canvas = new Canvas(b); myView.draw(canvas); – dMathieuD Dec 03 '10 at 16:04
  • myView needs to be displayed right? There is no way to do it another way? (Sorry for multiple comments, wrong manip) – dMathieuD Dec 03 '10 at 16:05
  • That's ok -- if you don't know what size bitmap you're going to need, you could create the bitmap at say full screen size -- use DisplayMetrics to get height and width -- and then use Canvas' drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) method to scale the bitmap to the right size, once you know it. Then you can create the bitmap independently of the view, and scale it when you need to draw it. – Tim Barrass Dec 03 '10 at 16:55