java - 如何在Java中渲染倾斜的图像?

标签 java image-processing image-manipulation

我的问题是我有一个渲染图像的 Java 应用程序。现在我想渲染一个倾斜的图像。

一种简单的方法是获得倾斜的图像,然后渲染它,但我的目标是根据窗口中的鼠标移动来倾斜图像。

对此的一种可能的解决方案是在不同倾斜角度提供多个图像,并在鼠标移动时渲染它们,但这种实现的精度有限,并不完全是我想要的。

有没有办法动态渲染倾斜图像?

提前致谢。

最佳答案

我完全同意上一篇文章,AffineTransform 是正确的选择。这是一个简单的例子......

import java.awt.*;
import java.awt.geom.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;

public class RotateImage {
    private static final int PANEL_WIDTH = 600;
    private static final Dimension MAIN_SIZE = new Dimension(PANEL_WIDTH, PANEL_WIDTH);
    private static final int SLIDER_MIN = -180;
    private static final int SIDER_MAX = 180;
    private static final int MAJOR_TICK = 30;
    private static final int MINOR_TICK = 15;
    private static final String URL_PATH = "http://duke.kenai.com/guitar/DukeAsKeith-daylightSmall.png";

    private JPanel mainPanel = new JPanel();
    private JPanel drawingPanel = createDrawingPanel();
    private AffineTransform transform = new AffineTransform();
    private JSlider rotationSlider;
    private Image image;

    public RotateImage() {
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(drawingPanel, BorderLayout.CENTER);
        mainPanel.add(createTransformPanel(), BorderLayout.SOUTH);

        URL url;
        try {
            url = new URL(URL_PATH);
            image = ImageIO.read(url ); 
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private JPanel createTransformPanel() {
        rotationSlider = new JSlider(SLIDER_MIN, SIDER_MAX, 0);
        rotationSlider.setMajorTickSpacing(MAJOR_TICK);
        rotationSlider.setMinorTickSpacing(MINOR_TICK);
        rotationSlider.setPaintLabels(true);
        rotationSlider.setPaintTicks(true);
        rotationSlider.setPaintTrack(true);
        rotationSlider.setSnapToTicks(true);
        rotationSlider.addChangeListener(new SliderListener());

        JPanel transformingPanel = new JPanel(new BorderLayout());
        transformingPanel.setBorder(BorderFactory.createEtchedBorder());
        transformingPanel.add(rotationSlider);
        return transformingPanel;
    }

    @SuppressWarnings("serial")
    private JPanel createDrawingPanel() {
        if (drawingPanel != null) {
            return drawingPanel;
        }
        drawingPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                myPaint(g);
            }
        };

        drawingPanel.setPreferredSize(MAIN_SIZE);
        return drawingPanel;
    }

    private void myPaint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(3));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        AffineTransform oldTransform = g2.getTransform();
        if (transform != null) {
            g2.setTransform(transform);
        }
        if (image != null) {
            g2.drawImage(image, 70, 70, null);
        }
        g2.setTransform(oldTransform);
    }

    public JComponent getPanel() {
        return mainPanel;
    }

    private class SliderListener implements ChangeListener {
        public void stateChanged(ChangeEvent e) {
            double theta = Math.PI * rotationSlider.getValue() / 180;
            double center = (double) PANEL_WIDTH / 2;
            transform = AffineTransform.getRotateInstance(theta, center, center);
            drawingPanel.repaint();
        }
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("RotateShape Application");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new RotateImage().getPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

关于java - 如何在Java中渲染倾斜的图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4353615/

相关文章:

java - Java Swing 中的 PropertyGrid

java - 找不到 R.layout - 应用名称。只有安卓布局

python - 如何在OpenCV中构造二值图像的水平投影

python - 为什么 kinect v1 保存的深度图像太黑

java - java/kotlin 方程中的时间顺序和加法函数

java - 前一个变量的值变为当前变量的值

javascript - 当我将缩略图附加到 DIV 时,如何以特定模式定位缩略图?

ios - 从照片库中裁剪 UIImage 与 iPhone 相机

c++ - 使用 C++ FindContours 在视频图像中查找轮廓的问题

c# - 在 C# 中将 Bmp 转为 jpg/png