Is there any possible way to put all the drawn objects into an array? This is just for a drawing game so it is possible to save all objects and load them back from this way.
Thanks if this is possible!
Take a look at Picture class - http://developer.android.com/reference/android/graphics/Picture.html
After it's being attached to the canvas, it records all drawing operations and stores it.
After you can either draw all of them on another canvas, or store/transfer the Picture to make it on another device or later.
UPD: something like this
Picture picture = new Picture();
Canvas canvas = picture.beginRecording(300, 300);
canvas.drawRect(new Rect(5, 5, 10, 10), new Paint()); // configure paint here
picture.endRecording();
picture.writeToStream(new FileOutputStream("stored_drawing.pict"));
Now you'll be able to restore this rectangle from file and draw it on any another canvas.
So generally you can wrap you user's drawing through this class and it wil store all user drawing operations.
Good luck
Related
Very simple question, but I could not find the answer in JavaFX docs or StackOverflow:
I have a JavaFX Canvas filled with a graph (various calls to strokeLine(), not the issue here). I need to be able to draw a rectangle over this graph, then simply clear the rectangle, without affecting the graph in the background. (Like an undo operation).
Code to draw the rectangle ('p' and 'e' are points):
gc.rect(p.getX(), p.getY(), e.getX()-p.getX(), e.getY()-p.getY());
gc.stroke();
The most obvious answer would be to use the clearRect() method, but the problem is that it clears also the portion of the graph in the background...
So the question is: how do I clear a drawing that was made with stroke(), without affecting the other drawings in the background?
You can't do this with one canvas.
Canvas only store the result of your painting operation.
This is the interest of the canvas you can stroke million times the same line and it will only store and represent the result and doesn't consume more memory.
So you if you need to draw Something over your chart you should put an other canvas over the chart and draw on the second canvas.
It might be more straight forward and much more the JavaFX-way of doing things if you just put your canvas into a Group and then just add a Rectangle node to the Group which you can remove at any time if you want.
This can be acheaved by taking snapshot(s) of your Canvas, using the .snapshot(SnapshotParameters params, WritableImage image) method. Basicly, every time you draw something on your Canvas, you take a snapshot of it and store it somewhere (for example in a ArrayList). Then you can use those snapshots to create a 'undo' operation, by using the . drawImage(Image img, double x, double y) method of Canvas's GraphicsContext, in which you would pass the snapshot you want to go back to as the Image parameter.
I am trying to serialize a Canvas instance (using the Serializable interface) on which I have painted some pixels like the following code suggests:
Canvas board = new Canvas();
Graphics g = board.getGraphics();
g.setColor(Color.BLACK);
g.drawString("txt", 10, 20);
g.dispose();
Then when I serialize board it doesn't save the pixels I've painted. I'm guessing this is because by using getGraphics() I am not saving those pixels to any instance, so I thought that perhaps I should instead paint from within the Canvas's paint() method. Would serializing the Canvas then save the modified pixels too? If not, what are my options to save/serialize a Canvas with the pixels I've modified? I am guessing I would have to serialize the Graphics object instead of the Canvas? I am new to Java graphics, any help will be greatly appreciated.
To be more clear, what I'm trying to do is have the pixels I've put on a Canvas instance saved to a file using serialization. Then later I need to reload this Canvas instance from the serialized file I saved earlier, so that when I use it on the screen I see the exact same pixels I modified just before I serialized the Canvas. I know how to serialize objects and all that. I am just unclear where all the pixels are stored.
Update1:
The way the user draws something on the screen is by left-clicking on the Canvas area. Then MouseListener calls the following method, passing along the Point object specifying the mouse xy:
private void drawAt(Point p)
{
Graphics g = board.getGraphics();
g.setColor(brushColor);
g.setFont(brushFont);
g.drawString(brushText, p.x, p.y);
g.dispose();
}
Don't serialize Canvas or any other GUI components as you'd be serializing the "View" portion of your program, a risky thing to do (high risk for serialization exceptions due to attempting to serialize and unserialize unserializable sub components) and an inefficient thing to do -- serializing large amounts of data which are built automatically by the JVM and thus don't need serialization.
Instead you will want to serialize the "Model" portion of your data, that portion which holds the logical data of your program. So if your GUI is drawn using data held by an ArrayList, or a collection of ArrayLists, or whatever data it takes, then serialize that data. Then be sure to create your GUI so that can be built using the serialized data.
Or if you need to store an image, then store an image, probably best as a loss-less png file.
Also, I suggest that you draw into a BufferedImage, that you then display that BufferedImage within the paintComponent method override of a JPanel, and that you then save and restore the image. For more on how to draw and save, please have a look at these links. The first two contain my code, the third is that of MadProgrammer's:
Save image from JPanel after draw,
Convert a Graphics2D to an Image or BufferedImage and
Paint BufferedImage on JFrame and write to File.
I'm making a simple side scroller game in Java but am having trouble making the camera move with the person. My plan was to create a buffered image that could adjust the region of the image that is displaying and simply have it follow my character. However, I couldn't find any functions in the API to change the region of the buffered image that's displayed, so how could I do this? Thanks for any help provided.
//The level is created in an 800x400 pixel size, is there any way I can change
//the region myImage displays?
myImage = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
Well while you will be drawing your image you have a lot of options for example this function can draw any rectangle from your original image on any rectangle of the surface you get Graphics object from.
I`m building an android App, and i got stuck with a simple thing: How do i draw (or "add") a Canvas object, to another Canvas object, like "merging" them?
If that`s not possible, what is the best solution for doing that?
Thanks!
This depends entirely on your implementation.
If each Canvas draws objects directly from an array (of shapes, etc.) each frame, you could simply append one array to the other. This way, your Canvas does not need to be drastically altered, it only has to add one array to another (possibly an ArrayList would be the way to go here).
If the above is not the case, you may have to make some more drastic changes. When I encountered a similar problem, I created a new method called commitChanges(), which added a series of changes to an existing Canvas (adding lines on top, etc.).
I first invalidated the affected area, then created a Bitmap with the size of the Canvas: Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGBA_8888);.
Next, I created a canvas from that Bitmap: Canvas workingDrawing = new Canvas(bmp);.
Then, I drew everything I needed onto that new Canvas. In this case, that would be the data from one of your Canvases.
Now, in your other Canvas, you have to get the Bitmap you just drew, then draw it onto this Canvas. Like so: canvas.drawBitmap(yourDrawnBitmap, 0.0f, 0.0f, null);.
I think the difficulty you'll face is transferring the data from one Canvas to another. But, regardless of your implementation, one of the above methods should work effectively for you.
I want to create a number of straight lines connecting small circle shapes. then I want to change the color and width of the lines from within my program. I was thinking of using Canvas to do this but there does not seem to be a way to access individual shapes drawn on canvas to change their attributes after they are drawn. What would be an easy way to implement this?
First of all, what version of Java and which UI toolkit? AWT's Canvas is very dumb, it will not even "remember" what you have painted; when you minimize and restore the window, it will send a paint() event because it wants to be repainted.
The easiest way (if you are using AWT and stuck to Canvas) is to have a List of your shapes (either one list for all or one for circles and one for lines, or whatever you like) and make your paint method draw all of them. Then update the objects in your list. When you are done updating, call repaint() on your canvas and it will call paint() for you again.
You don't paint shapes onto a Canvas if you're using Graphics and Graphics2D functions like drawRect, drawPolygon, drawOval, etc. Once they're drawn, they don't exist as shapes anymore. You just have an image with filled-in pixels.
As mihi said, you may have to keep track of the shapes you're trying to draw, then regenerate your image if it changes. Perhaps you could also "unpaint" a shape you're trying to change by painting over it in the background color and repainting the changed shape.