This seems like an easy task, but I've literally searched for hours and haven't found anything so far. I have an ImageIcon which I would like to rotate by a certain angle.
What would be the simplest way to do this?
Edit: I tried converting the ImageIcon to a BufferedImage, and rotating the Graphics2`bPlayerImage = new BufferedImage(
playerSize, playerSize, BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D)bPlayerImage.getGraphics();
g.rotate(Math.toRadians(turnAngle));
g.drawImage(playerImage, x, y, null);`
The image doesn't appear to rotate.
Related
by using Canvas and JS I can draw a shape like this and have the x,y of each point :
Tha area can be choosen by more than 4 points, look at this link to have an idea.
I need to save and crop the image of the selected area by using the points. I can not use BufferedImage as it is just rectangular. Which lib in java I can use?
Okay, so starting with...
I used...
BufferedImage source = ImageIO.read(new File("Example.jpg"));
GeneralPath clip = new GeneralPath();
clip.moveTo(65, 123);
clip.lineTo(241, 178);
clip.lineTo(268, 405);
clip.lineTo(145, 512);
clip.closePath();
Rectangle bounds = clip.getBounds();
BufferedImage img = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
clip.transform(AffineTransform.getTranslateInstance(-65, -123));
g2d.setClip(clip);
g2d.translate(-65, -123);
g2d.drawImage(source, 0, 0, null);
g2d.dispose();
ImageIO.write(img, "png", new File("Clipped.png"));
to generate...
Now, the image is rectangular, that's just the way it works
Now, setClip is quite rough and isn't effect by any RenderingHints, you could make use of "soft clipping" instead, which is more involved, but generates a nicer results. See this example and this exmaple for more details
I am currently trying to get some kind of 2D dungeoncrawler (think: roguelike) running. Now I want to work with square tiles (32x32) but I wonder if there's a way to make my textures in a higher resolution, say 64x64, and scale them down onto a 32x32 square?
I imagine there has to be since almost all games do this in one way or another but all I can seem to find online is about 3D stuff.
Yeah. When you draw an image, you can add the new width and height to it to resize it.
public static BufferedImage resizeImage(BufferedImage image, int newwidth, int newheight) {
BufferedImage image2 = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_INT_ARGB);
Graphics g = image2.getGraphics();
g.drawImage(image, 0, 0, newwidth, newheight, null);
g.dispose();
return image2;
}
Refer to here for more info.
I'll start of by showing examples of what's wrong then I'll explain how, and finally I'll ask my question.
This is the picture I want to rotate.
I am rotating it 90 degrees and 270 degrees, on multiple occasions and then combiningthose into a big buffered-image.
The code I am using to rotate a single bufferedImage is this:
public static BufferedImage rotate(BufferedImage img, int angle) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.rotate(Math.toRadians(angle), w/2, h/2);
g.drawImage(img, null, 0, 0);
return dimg;
}
The out come of the rotation looks something like this.
The reason those black bars are these is because in the code you can clearly see I create a separate buffered-image which will be the final image.
Which uses the original width and hight, since the image is rotated the with and height switch so I compensated for this by changing BufferedImage dimg = new BufferedImage(w, h, img.getType()); to BufferedImage dimg = new BufferedImage(h, w, img.getType());.
I though it would be logical that this would solve my problem.
But I was wrong now the rotational outcome is this.
So from this point on is where I have no clue why it's doing this.
I might just be overlooking a tiny thing, or it's a common error even though I can't find any instance of this occurring.
So here is my question to you, why does it do this? And how do I fix this.
The image isn't square. If you rotate it by 90°, then you will create a gap that you need to fill.
Solutions:
Make sure the image is square
"Rotate" the size: When you rotate by 90° or 270°, you need to create a target image with swapped width and height (i.e. 200x100 -> 100x200)
Crop the image. Good in your case since scaling will make the arrow look bad but it might be out of center
Scale the image. If it's 609x579, scale it down to 579x579 (scaling down will usually look a little bit better).
Find the border color and fill the gap with the border color after the rotation
I figured it out.
The thing I was doing in the start was rotating the host image (dimg),
and then drawing the original image to it.
I could just as well have tried to fit a square in a circle my earlier rotation actually makes no sense at all.
So what I need to do is first create the host, draw the image to the host, the rotate the host and return it as the final image.
public static BufferedImage rotate(BufferedImage img, int angle) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, null, 0, 0); //Draw before rotating
g.rotate(Math.toRadians(angle), w/2, h/2); //Rotating after drawing
return dimg;
}
I hope this helps out some other people as well
if you want to use a similar code as first code
this may help ( if you remove the comments and debug lines (such as painting the background) it has only the translate((W-w)/2,(H-h)/2) line in addition )
// do not forget to import static java.lang.Math.*
public static BufferedImage rotate(BufferedImage img, int angle) {
int w = img.getWidth(null);
int h = img.getHeight(null);
double rad = toRadians(angle);
double eps = 1e-3;
int W=(int)(abs(cos(rad))*w+abs(sin(rad))*h-eps)+1;//W after rotation(calculated by using a little geometry )
int H=(int)(abs(sin(rad))*w+abs(cos(rad))*h-eps)+1;//H after rotation
//you may use max value ( diameter of the rectangle ) instead of dynamic value but in that case you must be careful of the black edges ( in this case red edges )
// if 90 is not a divisor of angle then you can't fit a rectangle with that angle in another one so the red edges are inevitable
// but with calculated W and H this edges are minimum
BufferedImage dimg = new BufferedImage(W,H, BufferedImage.TYPE_INT_RGB);// you can change it to any type you want it's just a sample
Graphics2D g = dimg.createGraphics();
g.setColor(Color.RED); // background color of red for displaying the red edges when image is not completely fit
g.fillRect(0, 0, W, H);
int x=(W-w)/2;
int y=(H-h)/2;
g.translate(x, y); // moving dimg center to img center ( this was what first code lack in )
g.rotate(-rad, w/2, h/2); // now rotating dimg around the center of img ( which is now same as center of dimg )
// we rotate dimg by -rad and draw img normally , it's like rotating img by rad instead of dimg by -rad
g.drawImage(img,null,0,0); // and drawing
return dimg;
}
I want to make rectangles on a JLabel and the convert that rectangle into a BufferedImage... like layers in paint shop... drage that BufferedImage and resize...can anyone help
I have done this but it didnt work
Rectangle2D rectangle2D;
BufferedImage bi = new BufferedImage(bimg.getWidth(), bimg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D big = bi.createGraphics();
rectangle2D = new Rectangle2D.Float(eX, eY, sW, sH);
big.setStroke(new BasicStroke(5));
big.setColor(color);
shapePaint = new TexturePaint(bi, rectangle2D);
g2d.setPaint(shapePaint);
I want to make rectangles on a JLabel and the convert that rectangle into a BufferedImage
You are doing it the wrong way around. Draw to the buffered image, add it to a label, call label.repaint() to display any changes.
E.G.
As seen in..
This answer
This answer
This answer or..
..For an animated version, this answer
I have been looking up a lot of examples, every time I try, my image becomes offset, and also not rotated by the degree I am looking for.
I have a class which extends JPanel, and draws an image. This JPanel is then put into my JFrame. I need to have a method, which when I click a button can take the image of the JPanel, rotate it, and return ( with the new height and width ). - Then I can ask the JPanel to repaint using the new image, and.. it should have rotated.
If someone could please help me with an example, of rotating 90 degrees, and returning with now the height = the old width, and width = old height, that would be amazing!
Thanks,
Here you are
Image rotatedImage = new BufferedImage(imageToRotate.getHeight(null), imageToRotate.getWidth(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) rotatedImage.getGraphics();
g2d.rotate(Math.toRadians(90.0));
g2d.drawImage(imageToRotate, 0, -rotatedImage.getWidth(null), null);
g2d.dispose();