Actual bounds of a rectangle when drawn with Graphics2D - java

How can I reliably determine the exact extent of a rectangle when it is rendered using Graphics2D?
Suppose I have a rectangle that originates at (20,40) and is 200 pixels wide and 100 pixels tall:
drawRect (20,40,200,100);
The answer to my question is easy when this is a simple rectangle, drawn crudely with a 1-pixel pen. However, what are the exact bounds that are affected in the rendering process when the pen is 2 pixels, 3 pixels, or more? And will the rectangle "spill over" to adjacent pixels when anti-aliasing is used?
What is the most reliable way to calculate the exact bounds that will be manipulated?

If you need to know the bounds of a stroked shape, you can stroke it yourself and check the bounds.
Graphics2D g;
g.getStroke().createStrokedShape(myRect).getBounds();

Related

How to make 2 intersecting rectangles go transparent

My goal is to fill the screen with a black rect with an alpha of 128 so the screen looks dark, then make it so I can render rects to the screen and the place they are rendered to turns fully transparent so you can see right through that rect. I have made the screen get filled partially black but I cannot make it go transparent when I draw a rect on top of that. I have never used AlphaComposites but I assumed that I'm gonna have to use one of those to make this work. Anyone know how I could get this done?
private Color darknessColor = new Color(0,0,0,128), flashlightColor = new Color(255,255,255,128);
public void render(Graphics g) {
// Draws the darkness part of the screen.
Graphics2D g2 = (Graphics2D) g;
g2.setColor(darknessColor);
g2.fillRect(0, 0, handler.getWidth(), handler.getHeight());
g2.setColor(flashlightColor);
g2.setComposite(AlphaComposite.DstOut);
g2.fillRect(200, 200, 300, 200);
g2.dispose();
}
There is no way to "undraw" a rectangle which has already been drawn; if you've already painted over the scene behind the rectangle, then it's gone. The solution is to only draw the black shape where you want it; this means it is not simply a rectangle, but if the part you want to "cut out" is a rectangle, then you could achieve the effect you want by drawing four black rectangles, like so:
Hopefully it's straightforward how to compute the coordinates that these four rectangles should have.

Java - drawing a scaled up shape with line thickness of 1

When you use Graphics2D.scale(); and draw a shape, the outline thickness is also scaled.
Is there a way to draw it without the line thickness being scaled? Perhaps there's another efficient way to scale it other than using the above function?
This question is similar. It looks like you have to mess around with a Stroke object to set the right line width.
You're going to have to save your drawing as a list of line vectors, and scale and render the drawing at various sizes to maintain the line thickness you want.
I've just found a solution to my own question. I've no idea how efficient it is but it works as intended:
Area area = new Area(myShape); //myShape is the shape I want to scale
AffineTransform at = new AffineTransform();
at.scale(2,2);
area = area.createTransformedArea(at);
graphics2d.draw(area); //graphics2d is the Graphics2D instance to do the drawing
Perhaps someone could enlighten me as to whether or not this is a good approach to take?

Graphics2D - Rotating Shapes on a Graphics2D object

I have a Graphics2D object which I use to draw on my Canvas. I draw multiple shapes on the Canvas and want to transform only one (or part) of them.
I'll try to keep this simple:
void render(Graphics2D g) {
... // Draw shape 1
... // Draw shape 2
... // Draw shape 3
}
How would I go about rotating shape 2 while leaving shape 1 and 3 intact? By "rotate" I mean rotating around its center point, which we can define as x and y for example.
I've been looking for a way to do this for a while now, but couldn't find anything that works the way I want it to.
Is there any simple way to do this?
Rather than rotating the shape around it's centre point, rotate and then translate the canvas. To rotate around the centre of the shape at (x, y), first translate the canvas by (-x, -y) and then rotate the canvas -d degrees and draw the shape as normal at (0,0).
When you're done, rotate back then translate back (note that with these geometric transformations the order is important, translating and then rotating will give you a completely different outcome).
This means that you can still draw an object at any rotation without having to recalculate the coordinates yourself.
AffineTransform afx = new AffineTransform();
afx.rotate(angleRad, s.getCenter().x, s.getCenter().y);
//afx.rotate(angleRad);
java.awt.Shape ss = afx.createTransformedShape(s.getPrimativeShape());
return ss;
s is my wrapper class for java.awt.Shape and does some stuff with it.... But what you want is in line 2.
afx.rotate(Angle,xAnchorPoint,yAnchorPoint);
afx.rotate rotates the object about the point (xAnchorPoint;yAnchorPoint).
Hope this is what you wanted
In order to rotate a shape, use one of the Graphics2D.rotate methods.
Cache the transform used for both shape 1 and shape 3. Before drawing shape 3, ensure that you reset the transform to the cached one, since using rotate for shape 2 will alter the current transform coordinates.
Steps:
Cache current transform
Draw shape 1
Rotate
Draw shape 2
Set transform to cached one
Draw shape 3

Rotate rectangle on an Image Swing

I have an Image on a JPanel. I'm then drawing a rectangle on top of the image like this:
Graphics2D image = (Graphics2D) g;
image.drawRect(......);
//create image code here.
image.rotate(1.5);
image.drawImage(....);
Problem is that when I rotate the image image.rotate(1.5), the rectangles stay in the same place.
I've tried creating the rectangle before rotating the image and after rotating the image, but both times it fails.
Is there an easy way to make the rectangles also rotate along with the image?
Thanks.
One approach is to rotate the graphics context's affine transform, as shown in this example. In that way, all drawing will be rotated by the same amount.
You might want to try using Rectangle, an implementation of the Rectangle2D class, then use g2d.draw(rectangle). This might be able to get the rotation state from the Graphics2D object better.

Round corners on images using Java and JAI

We're using JAI (https://jai-imageio.dev.java.net/) to scale and crop images in Java. We would like to create round corners on our images. How do we do that?
The images are JPG and PNG. I would think it's easier to do this with JPGs?
The image is a PlanarImage from JAI
PlanarImage src = JAI.create(...,...);
which can be transformed to a java.awt.Graphics object
Has anyone done this before?
PNG supports a transparent alpha channel, but JPG does not. So, for JPG you would have to also pick a color to paint the "invisible" part of the rectangle for the rounded corners.
There is a class java.awt.geom.RoundRectangle2D available to do this:
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
RoundRectangle2D rr = new RoundRectangle2D.Float(50, 50, 200, 100, 10, 10);
g2d.draw(rr);
}
The Float() method of the class RoundRectangle2D takes six arguments:
The first two represent the location of the upper left corner.
Arguments 3 and 4 represent the width and height of the rounded rectangle.
The last two arguments represent the width and height of the arc drawn in the
corners.
So, draw a rounded rectangle that will just contain the image you want to have rounded corners and then either overlay or use a mask to get the desired effect.
What prevents you from drawing whatever corners you like onto the Graphics object obtained from the Image? I'm not really sure what your "round corners" are supposed to look like, but you can perform all reasonable paint operations on the Graphics object.

Categories