in my layout I have a background, button and a textView, the button here serves to convert my view to bitmap and save it
I managed to do that but my png Image contains the save button as well,
I'm using this line to get the drawing from my layout :
Bitmap cache = vw.getDrawingCache();
What I want to achieve is that before getting the screen from the view , I want it to not consider my button.
Thanks in advance.
Using canvas to draw layout like this
Bitmap bitmap = Bitmap.createBitmap(layout.getWidth(), layout.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
layout.draw(canvas);
Have you looked at setting the component to visibility gone?
Button saveButton = (Button) findViewById(R.id.save_button);
saveButton.setVisibility(View.GONE);
Then after you get your snapshot make sure you do
saveButton.setVisibility(View.VISIBLE);
The problem with this solution is that the screenshot will still contain the gap where the button was. The view does not get redrawn before the bitmap is saved. I have tried calling invalidate() and requestLayout() with no success (which is why I found your question).
Also, another alternative is to do something like what Anand said by drawing it to a Canvas. This is useful if your view is larger than the screen. By drawing it to a Canvas you can get the entire view. By going this route, you can have a container with your background and TextView and have the button outside that container. You can then get just the view with the container. (I can't use this solution since my button is in the middle of my desired data)
View v = findViewById(R.id.my_view); // the view containing your text view
// not needed since it is outside your my_view now
// v.findViewById(R.id.save_button).setVisibility(View.GONE);
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
// not needed since it is outside your my_view now
// v.findViewById(R.id.save_button).setVisibility(View.VISIBLE);
// your Bitmap "b" now contains the image you want
Related
So I want to put an xml-layout as a background to a view, but then it has to be a drawable. So is there any way to turn an it into a drawable?
I've also tried inflating it, but nothing works the way I want :(
Thx in advance.
Basically like #CommonsWare said.
1. Get the LayoutInflator of the activity
2. inflate the layout like inflater.inflate(R.layout.sample,null,false)
3. Create a canvas, that saves all the drawings into a defined bitmap like this
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
Draw the created view into the canvas like this
View v = inflater.inflate(R.layout.sample,null,false); // inflate view here
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
v.draw(c);
Use the bitmap, the canvas did draw
Consider saving the bitmap locally in terms of redrawing of the activity, see following explanation:
Depending on how dynamically and often you want to create this background via canvas you should furthermore consider to save the created bitmap somewhere (temporarily), because each time the layout changes (e.g. checkbox selection), the whole canvas has to be redrawn and the inflating process needs to be done a second time too, what can lead to runtime lags in the UI.
So just save this bitmap somewhere and reload it maybe, that's what i did in am similar case.
I've read pretty much every post on this topic, but none of them seem to help.
I'm trying to capture a screen shot of the current screen. For this I'm using getDrawingCache. Here's my code:
mRootView.get().setDrawingCacheEnabled(true);
mRootView.get().buildDrawingCache();
Bitmap screenShot = Bitmap.createBitmap(mRootView.get().getDrawingCache());
mRootView.get().setDrawingCacheEnabled(false);
The resulting bitmap is always black.
mRootView is a weak-reference to the drawer layout, which is my root view.
Here's what I've tried:
Adding a measure and layout call (although this shouldn't be needed since this code runs when a button is pressed, so the view should already be layed out).
Setting the layer type to LAYER_TYPE_NONE before calling setDrawingCacheEnabled(true)
Using a different view as the root view (for example, a ViewPager inside the DrawerLayout).
Nothing seems to work and I've run out of ideas.
You can draw your view to canvas-
pass your main layout reference to this method-
Bitmap file = save(layout);
Bitmap save(View v)
{
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
If above solution not working so just follow this link might be helpful convert view to bitmap
Currently I am writing a program that is supposed to add an image to a canvas and then add that canvas to a relative layout. The problem that I am having is that when I call this the layout is displayed but the canvas is not drawn on the layout.
canvas = (RelativeLayout) findViewById(R.id.canvasLayout);
imageCanvas = new Canvas();
mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageCanvas.drawBitmap(mainImage, 50, 50, null);
imageCanvas.drawColor(Color.BLACK);
canvas.draw(imageCanvas);
That is the code that is attempting to add the image to the canvas and then the canvas to the layout.
I am completely lost as to what to do to attempt to fix this.
The canvas.draw(imageCanvas) call you are using actually draws canvas (the RelativeLayout) onto imageCanvas (the Canvas object) - likely not what you were intending. There are several ways I would suggest to go about getting the drawable onto the RelativeLayout:
The first would be to create an ImageView, set it's image to your drawable, then add it to the layout. Depending on if you want the images to be added dynamically during runtime or not, you could actually do this in the xml graphic designer. This is probably the best way to go, as it gives you control over how large the image is, and how it gets scaled/cropped.
If you want to set a background to the layout, I believe you can actually set the Background attribute of the RelativeLayout directly to a drawable - this does not allow as much control over the scaling of the image though.
Finally, for complete control over how the RelativeLayout is draw, you can override the OnDraw method in any view. This method is called by the android system whenever it needs to refresh the view. If you do end up using this, creating a custom view class, which you then place in the RelativeLayout will probably work better.
canvas = (RelativeLayout) findViewById(R.id.canvasLayout);
imageCanvas = new Canvas();
mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageCanvas.drawBitmap(mainImage, 50, 50, null);
canvas.addView(imageCanvas);
The following will programmatically add an image to your layout from a bitmap resource which sounds like what you want to do. If you need to draw on top of that image, say, you would need to make a custom component by extending ImageView and overriding onDraw().
canvas = (RelativeLayout) findViewById(R.id.canvasLayout);
imageView = new ImageView(getApplicationContext());
mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageView.setImageBitmap( mainImage );
canvas.addView( imageView );
I have prepared a custom view. My view contains one alphabet which i have drawn using drawText in onDraw().Now i need to change this view to bitmap.
Here my OnDraw() is,
public void onDraw(Canvas canvas) {
drawText("A",100,200,mPaint);
}
I need to convert this view to bitmap...please help me...thanks in advance .
For those that already have their views set up and want a shorter solution than AutoCoders:
Bitmap result = Bitmap.createBitmap(dst.getWidth(), dst.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
dst.draw(c);
After this the Bitmap 'result' will contain your view.
'dst' is the View you want as a bitmap.
Bitmap viewCapture = null;
theViewYouWantToCapture.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(theViewYouWantToCapture.getDrawingCache());
theViewYouWantToCapture.setDrawingCacheEnabled(false);
In Android, the word “bitmap”, is a class that help us to work with images as a map of bits or an array of bits. This Bitmap class is very useful when we are working with graphics interfaces like Canvas or OpenGL.
Canvas, is another known class in Java, and is used to draw things. In Canvas we have control of all the pixels.
We need to have some variables initialized,
This is the Canvas we are going to draw in.
Canvas canvas = null
This is the layout we are going to use to create our view.
RelativeLayout relativeView ;
This is the background we are going to set in our view, we get it from a resource file (R.drawable.blackBgrnd). The BitmapFactory.decodeResource method is used to get a resource image and convert it in a Bitmap (we will use the Bitmap class). The object mContext (context) must be passed from the Activity we are working on.
Bitmap viewBgrnd = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.blackBgrnd);
We need another bitmap, to draw it on the canvas. We set the width and the height of this bitmap relative to the width and height we have created in our layout. Now this Bitmap is empty, but we are going to associate it with the canvas, so every time we draw in the canvas, it will be drawn in this bitmap object.
Bitmap returnedBitmap = Bitmap.createBitmap(relativeView .width, relativeView.height,Bitmap.Config.ARGB_8888);
First of all, we had the canvas = null, now we create a Canvas object using the auxiliary bitmap we had created before.
canvas = new Canvas(auxBitmap);
Now its time to create our view.
We can add Images, for example:
ImageView newImage = new ImageView(mContext);
newImage.setImageBitmap(bitmapWithImage)
We can set the imageView position in the view using “layout” method:
newImage.layout(l,t,r,b);
l Left position, relative to parent
t Top position, relative to parent
r Right position, relative to parent
b Bottom position, relative to parent
and finally adding it to our layout:
relativeView.addView(newImage);
or we can add text:
TextView newText = new TextView(mContext);
newText.setText(“This is the text that its going to appear”);
adding it to the layout in the same way:
relativeView.addView(newText);
Once we have added all elements we want to our layout, we have to create a paint object:
Paint paint = new Paint();
just to define default values of painting.
We use the “drawBitmap” method from the canvas:
canvas.drawBitmap(ViewBgrnd, 0, 0, paint);
and finally we call dispatchDraw in the layout to draw the children views (imageView, textView) in the canvas.
relativeView.dispatchDraw(canvas);
The returnedBitmap is the bitmap that contains the drawing of the views in the canvas, on it, we have the layout and its childrens as a Bitmap, after painting them in the Canvas.
Conclusion
This is really tricky and maybe difficult to understand. It took me time to understand how it worked. I will try to summarize it:
We need to create a empty bitmap. This bitmap will be the final bitmap with the views on it.
We create the canvas using that bitmap.
We create a layout and we add as many elements as we want.
We attach the layout to the canvas.
Because we have created the canvas using a bitmap object, all that is drawn in the canvas, will be drawn in the bitmap.
From: Bright hub
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.
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/
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);