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.
Related
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.
I have a quadrilateral drawn in Path2D, and I would like for there to be an image on it. More specifically, I am trying to draw an image of my choice to 4 different points on a quadrilateral. In my case, it is a parallelogram. I do not want the image to go over the paralellogram. A better way to see what I am trying to say is to see the screenshot below.
I would like the image to be transformed to fit the green area. Not clipped.
I want the image to be pinned over the green paralellogram. However. I do not want the image to go over into the blue paralellogram, or the white space foe that matter.
So far I have tried
Researching for a way to place images directly onto Path2D.Double() objects. No answer
Rotating the image to fit the paralellogram. Didnt work.
Using AffineTransform in java. Dont get it ;-;
Thanks. I am new to java so do try to be lenient?
One way is to:
create a separate BufferedImage.
Apply a transform to the new image.
Draw your image to that new image.
Use the Shape object for the green area as a clip on the main drawing area
Draw the transformed image onto the main drawing area.
It's been a while since I have done transformations. You may have to set the transformation first and then draw the image after. Transformation has to come first.
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.transform(AffineTransform.getShearInstance(1.0, 0));
g2.drawImage(image, 0, 0, this);
}
Here is a simple example of how transforms work. You will have to spend some time on figuring out what values you need to make it work or if you might need to manually create a transformation matrix yourself.
I can use this code
BufferedImage image = ImageIO.read(new File("toolbar.png"));
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
Graphics graphics = grayImage.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
to convert a BufferedImage from TYPE_3BYTE_BGR to TYPE_3BYTE_BGR.
For example , the input:
the output:
I know that the colored pixel is turned into a white pixel or a black pixel based on a computation rule. What's it and what can I do to adjust it? Thanks for your help in advance.
The conversion as in your code above, is an implicit conversion happening, because the input image (RGB) has more colors that the destination (binary indexed color).
The "rule" for this conversion to binary color can be described as simply "pick the color in the destination that is closest to the one from the input ". As your only colors are black and white, all colors that have the average of R, G and B less than 50% will become black, the rest white. There is no way to "adjust" this, directly.
However, you can control the threshold, either directly or compute it from the input, for better images. See for example this blog for an example.
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();
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.