Вращение экземпляров BufferedImage
У меня проблемы с поворотом BufferedImage
для отображения. Я думаю, что вращение работает просто отлично, но я не могу нарисовать его на экране. Мой код:
Class extends JPanel {
BufferedImage img;
int rotation = 0;
public void paintComponent(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
img2d = img.createGraphics();
img2d.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
g.drawImage(img, imgx, imgy, null);
this.repaint();
}
}
Это не работает для меня. Я не мог найти способ нарисовать повернутый img2d
на g
,
РЕДАКТИРОВАТЬ: у меня есть несколько объектов, которые рисуются на g
так что я не могу повернуть это. Мне нужно иметь возможность вращать вещи индивидуально.
4 ответа
Я бы использовал Graphics2D.drawImage(изображение, affinetranform, imageobserver).
Пример кода ниже поворачивает и переводит изображение в центр компонента. Это скриншот результата:
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");
frame.add(new JComponent() {
BufferedImage image = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// create the transform, note that the transformations happen
// in reversed order (so check them backwards)
AffineTransform at = new AffineTransform();
// 4. translate it to the center of the component
at.translate(getWidth() / 2, getHeight() / 2);
// 3. do the actual rotation
at.rotate(Math.PI/4);
// 2. just a scale because this image is big
at.scale(0.5, 0.5);
// 1. translate the object so that you rotate it around the
// center (easier :))
at.translate(-image.getWidth()/2, -image.getHeight()/2);
// draw the image
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image, at, null);
// continue drawing other stuff (non-transformed)
//...
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
Может быть, вы должны попробовать использовать AffineTransform
как это:
AffineTransform transform = new AffineTransform();
transform.rotate(radians, bufferedImage.getWidth()/2, bufferedImage.getHeight()/2);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);
Надеюсь это поможет.
Вы вращаете графику для рисования в свое изображение, а не изображение. Вот почему вы не видите эффекта. Примените вращение к графике, на которой вы рисуете, и оно будет рисовать повернутое изображение:
public void paintComponent(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
g.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
g.drawImage(img, imgx, imgy, null);
this.repaint();
}
Это, вероятно, не будет отображать полностью то, что вы ожидаете, вращение будет вращаться вокруг начала координат. Чтобы изображение вращалось вокруг его центра, перед поворотом необходимо применить перемещение координат, например:
g.translate(imgx >> 1, imgy >> 1);
У Graphics2D Tutorial есть еще несколько примеров.
Я знаю, что этот вопрос старый, но я придумал решение, которое имеет некоторые преимущества:
- создает изображение правильного размера.
- правильное смещение.
- не поворачивается без необходимости на 0° или 360°.
- работает для отрицательных углов (например, -90°).
- работает, когда ввод
BufferedImage.TYPE_CUSTOM
.
При этом предполагается, что угол кратен 90°. Единственное улучшение, которое может понадобиться, это использовать Enum для
angle
вместо того, чтобы просто
int
.
Вот мой код:
public static BufferedImage rotateBufferedImage(BufferedImage img, int angle) {
if (angle < 0) {
angle = 360 + (angle % 360);
}
if ((angle %= 360) == 0) {
return img;
}
final boolean r180 = angle == 180;
if (angle != 90 && !r180 && angle != 270)
throw new IllegalArgumentException("Invalid angle.");
final int w = r180 ? img.getWidth() : img.getHeight();
final int h = r180 ? img.getHeight() : img.getWidth();
final int type = img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType();
final BufferedImage rotated = new BufferedImage(w, h, type);
final Graphics2D graphic = rotated.createGraphics();
graphic.rotate(Math.toRadians(angle), w / 2d, h / 2d);
final int offset = r180 ? 0 : (w - h) / 2;
graphic.drawImage(img, null, offset, -offset);
graphic.dispose();
return rotated;
}