Вращение экземпляров 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;
}
Другие вопросы по тегам