Java 2D Graphics: can't overlay images - java

Im trying to get to grips wth java 2d graphics
Ive basically got a JPanel with a backgrounfd image in it like so:
public MapFrame(Plotting pl){
this.pl =pl;
this.setPreferredSize(new Dimension(984,884));
this.setBorder(BorderFactory.createEtchedBorder());
try {
getFileImage("stars.jpg");
}
catch (Exception ex) {
}
this.addMouseMotionListener(this);
this.addMouseListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bg, 0, 0, null);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(0x756b48));
g2d.drawLine(0,0,0,100);
}
private void getFileImage(String filePath) throws InterruptedException, IOException {
FileInputStream in = new FileInputStream(filePath);
byte [] b=new byte[in.available()];
in.read(b);
in.close();
bg=Toolkit.getDefaultToolkit().createImage(b);
MediaTracker mt=new MediaTracker(this);
mt.addImage(bg,0);
mt.waitForAll();
}
In paint component I want to overlay small images 12x12 pixels in a loop at various xy points that ill get from some xml.
Cant seem to get an image to overlay over my first one
Im a bit lost here and v rusty
Any help would b gr8

public void paintComponent(Graphics g) {
g.drawImage(bg, 0, 0, null);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(0x756b48));
g2d.drawLine(0,0,0,100);
for(SomeXMLObject o : yourXMLSource) {
g.drawImage(yourImage, o.x, o.y, null);
}
}
Please specify clearer how your XML is parsed, if you already did that. Then, you'd also need to load the "12x12" image. SomeXMLObject is a structure containing x and y variables, extracted from your XML.
If you call g.drawImage(...) after the background: it will be painted after the background, and thus overlay. Be sure you load a png-24 image, to enable translucency-areas, if you'd want that.

If you want to paint an image at various locations, it is as simple as calling Graphics.drawImage(Image, int, int, ImageObserver) multiple times for different coordinates (as shown in the previous answer).
As for loading images, I'd recommend using one of the ImageIO.read methods instead of doing it yourself.

You probably want to use use the ImageIO library to load your image. If you have an image filename all you need to do to load it is
BufferedImage bimg = ImageIO.load(new File(filename));
That's a little easier then the code you have above.
After that, like other people said you can use the g.drawImage(bimg,x,y,this); to actually draw the images.

Oh Dear
Id formatted the filenames of my resources wrong
what a donkey I am
All good advice I think though guys

Related

How can I paint an image from BufferStrategy to Png file?

I've created a Java program that generates snowflakes and I'd like to save the image created as a .png file once the program finishes drawing.
I've searched on Internet, but I've found only programs using BufferedImage, while I use a BufferStrategy, so I don't know exactly where to start.
The draw method in my program uses a BufferStrategy to create the Graphics component.
For example, to draw a simple line the method is:
bs = display.getCanvas().getBufferStrategy();
if (bs == null) {
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.clearRect(0, 0, width, height);
g.setColor(Color.BLACK);
g.drawLine(0, 0, 50, 50);
What I would like is to get an exact copy of what has been drawn on the screen by the program to be saved as a .png image.
Hope you can help me.
Why not take a screenshot and then past it onto MS paint or some other(and better) image editing software like Photoshop or fire alpaca? That should solve your problem.
The common denominator between BufferedStrategy and BufferedImage is Graphics, so you want to write a paint routine so that you can simply pass a reference of Graphics to it
public void render(Graphics g) {
g.clearRect(0, 0, width, height);
g.setColor(Color.BLACK);
g.drawLine(0, 0, 50, 50);
}
Then you can pass what ever context you want.
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_RGB);
Graphics2D g2d = img.createGraphics();
render(g2d);
g2d.dispose();
Then you can use ImageIO.write to write the image to disk. See Writing/Saving an Image for more details

How to set an image instead of white color in this code?

I am trying to make some sort of a Paint program but in JAVA. With the graphics class, I can set a painting space and draw on it. I want this space to be an image instead of a white space and despite all my efforts, I can't. If I succeed, I can't draw over the image.
non-working code with image: https://pastebin.com/zNnWGjgS
Stackoverflow forces me to put some code here but it's too long
working code without image: https://pastebin.com/r1nFHY9c
Stackoverflow forces me to put some code here but it's too long
Please help me guys. Thank you.
With just a quick look at you paintComponent I can see that you are confused. All you want to do is to load the graphics of your image into the Graphics2D g2 and draw lines on it. In your non working example you :
Create a new image with createImage(getSize().width, getSize().height);
You set the graphics g2 to empty Image graphics
You load the image and discard the previous initialization leaving the g2 with the empty one.
You drawing the image, while all the changes are made to the g2 graphics.
To fix your error just change the paintComponent to :
#Override
protected void paintComponent(Graphics g) {
if (image == null) {
try {
image = ImageIO.read(new URL("https://i.imgur.com/mjxu50B.png"));
} catch (Exception e) {
e.printStackTrace();
}
g2 = (Graphics2D) image.getGraphics();
// enable antialiasing
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLACK);
}
g.drawImage(image, 0, 0, null);
}
PS. In future post try to post the non working example only and try to keep it as simple as you can.

Save a drawn picture on a JPanel in a file [java]

I've made a code to draw on a Jpanel
frame1.add( new JPanel() {
public void paintComponent( Graphics g ) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.white);
g2.fillRect(0, 0, width, height);
//Drawnig Part
});
Every thing is OK
Now My question is how to save what I've drawn on my JPanel in a file a.PNG or any other type
I have spent a lot of time to write the Drawing Part, So it will be helpful if you can suggest a solution by changing the required parts of my code, instead of rewriting the whole code.
I suggest that you buffer your drawing operations with a BufferedImage, like so:
// This should not be done in the draw method, but rather when
// the frame is created. You should also make a new buffer image when
// the frame is resized. `frameWidth` and `frameHeight` are the
// frame's dimensions.
BufferedImage bufferImage = new BufferedImage(frameWidth, frameHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D bufferGraphics = bufferImage.createGraphics();
// In your draw method, do the following steps:
// 1. Clear the buffer:
bufferGraphics.clearRect(0, 0, width, height);
// 2. Draw things to bufferGraphics...
// 3. Copy the buffer:
g2.drawImage(bufferImage, null, 0, 0);
// When you want to save your image presented in the frame, call the following:
ImageIO.write(bufferImage, "png", new File("frameImage.png"));
The Java Tutorial on Creating and Drawing to an Image, along with the ImageIO API reference might be helpful should you require more information.
Have a look at Writing/Saving an Image for more details, but essentially you can do something like...
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
// Draw what ever you want to to the graphics context
g2d.dispose();
ImageIO.write(img, "png", new File("My Awesome Drawing.png"));
If you can't separate the drawing logic from your panel, you could simply use the Graphics context from the BufferedImage to paint the the component with.
Have a look at Exporting a JPanel to an image and Print the whole program layout for examples

fillPolygon slows down my application tremendously

I'm creating a java implantation of http://alteredqualia.com/visualization/evolve/, as a hobby project. I'm using HW-accelerated Graphics2D to draw the polygons on a bufferedImage, which works, but the calling of fillPolygon() so many times cripples the application in terms of speed.
So now my question is: Is there any way to speed up this process?
private BufferedImage createImage() //Gets called once
{
BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
bImage.setAccelerationPriority(1);
Graphics2D g2d = (Graphics2D) bImage.getGraphics();
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_SPEED);
this.g2d = g2d;
return bImage;
}
private void reDraw() //Gets called every frame
{
drawBackground(g2d);
for(int i = 0; i < polygonList.getLength(); i++)
{
polygonList.get(i).draw(g2d);
}
}
public void draw(Graphics2D g2d)
{
if(rgba[3] != 0f)
{
g2d.setColor(new Color(rgba[0], rgba[1], rgba[2], rgba[3]));
g2d.fillPolygon(this);
}
}
With the use of java.awt.Graphics there is not much you can do on your end to improve performance except the usual optimizations of Java (reducing object creation and function calls etc). You can however choose how it renders on its end with the RenderHints as I see you are doing; I would suggest you set all the hints to speed including disabling antialiasing because that is actually one of the biggest hits.
Apart from that I can see you are using some array of what I can assume are ints and creating a colour with them, now I'm not sure what class this is from (assuming it's all from one class, please correct me) - nethertheless the if statement could be a return instead (that wont help much), and you should cache this Colour when it changes, I suggest not using the rgba array and using one global Color instance and then use getRed/Green/Blue if you ever need them.
If you would like more advice you can move this to Code Review

Seeing pixels of a SVG file when scaling in Java

I am handling a SVG file in Java using Batik library. The problem occurs when i scale it. I can see pixels of lines. Off course this should not happen, i should be able to zoom at least about 4000% and maintain the smoothness.
SVG file is read from an extended class, and it is painted from an override paint method. First i set new scale to AffineTransform variable, apply this to graphics of the method and paint using super.paint().
I am really stuck and can't figure out the problem. SVG files I am using are ok, I opened them in Inkscape and could zoom without the pixels showing. Please help.
code:
#Override
public void paint(Graphics g) {
try {
rad = (int)(radInit*zoom);
updateTransform();
Graphics2D g2d = (Graphics2D) g;
g2d.setTransform(transform);
super.paint(g);
paintElements(g2d);
} catch(NullPointerException nulle) {
// System.out.println("SVG not loaded yet");
}
}
private void updateTransform(){
transform = new AffineTransform();
transform.translate((-1)*zoom*centarX, (-1)*zoom*centarY);
transform.scale(zoom, zoom);
}
What was needed was
this.setRenderingTransform(transform, true);
This way no pixels can be seen or rather, everything is painted as it should be.

Categories