【问题标题】:Rescale a drawing in Java (JFrame)在 Java (JFrame) 中重新缩放绘图
【发布时间】:2016-07-06 23:46:26
【问题描述】:

我需要最简单的方法来重新缩放 java 中的图形(例如矩形......)。我找到了一种“拉伸”它们的方法:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.Dimension;

public class Stretch extends JFrame {
    int originalHeight = 600;
    int originalWidth = 600;
    public Stretch() {
        super("Stretch");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(originalWidth, originalHeight);
    }
    public static void main(String[] args) {
        Stretch s = new Stretch();
        s.setVisible(true);
    }
    public void paint(Graphics g) {
        Dimension size = this.getBounds().getSize();
        int rectWidth = 100;
        int rectHeight = 130;

        g.setColor(Color.white);
        g.fillRect(0, 0, size.width, size.height);

        g.setColor(Color.black);
        g.drawRect(100, 100, rectWidth + size.width - originalWidth, rectHeight + size.height - originalHeight);

    }
}

如你所见,公式是这样的:

g.drawRect(100, 100, rectWidth + size.width - originalWidth, rectHeight + size.height - originalHeight);

现在如何重新缩放绘图?宽度和高度必须保持相同的比例。 谢谢。

【问题讨论】:

  • 我不确定这幅画是什么。是长方形吗?还是矩形只是更复杂绘图的占位符?
  • 不管怎样,如果你想缩放矢量图如问题的矩形,又想保持比例,只需通过保持比例重新计算目标尺寸:先计算比例,然后选择一个宽度(或高度)并将其乘(或除)以得到另一个维度。
  • 最简单的方法是使用RectangleRectangle2D 并简单地对其应用缩放的AffineTransform。否则,您可以缩放属性或 Graphics 上下文
  • 对于shape resizing exampleGraphics scaling 或者如果你真的很冒险this example
  • 鉴于对我的回答的评论,问题显然不是关于重新缩放绘图,而是关于计算一些值以使其看起来像你想要的那样。更清楚一点。

标签: java jframe


【解决方案1】:

基本上有两种不同的方法:

  • 您可以“缩放整个Graphics
  • 您可以缩放实际形状

在某些情况下差异可能很细微,但可能很重要:当您缩放整个 Graphics 时,所有内容都会被缩放。特别是,当你将它缩放到2.0 左右,然后画一条宽度为1.0 的线时,这条线将被画出2 个像素宽。这是否需要取决于应用案例。

为了缩放实际形状,不能使用drawRect 方法。相反,您必须创建代表几何形状的Shape 实例。然后,您可以使用 AffineTransform#createTransformedShape 创建这些形状的缩放版本。

这是一个比较两种方法的示例(并更正了您的代码中存在的一些其他问题)。在这两种情况下,都会绘制原始大小为 (10,13) 的相同矩形,并按 5.0 倍缩放。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ScalingDrawnObjects
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ScalingDrawnObjectsPanel p = new ScalingDrawnObjectsPanel();
        f.getContentPane().add(p);
        f.setSize(600,400);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class ScalingDrawnObjectsPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;

        Shape rectangle = new Rectangle2D.Double(2, 2, 10, 13);

        g.setColor(Color.RED);
        drawWithScaledGraphics(g, rectangle);

        g.translate(100, 0);

        drawScaledObject(g, rectangle);
    }

    private static void drawWithScaledGraphics(Graphics2D g, Shape shape)
    {
        AffineTransform oldAt = g.getTransform();
        g.scale(5.0, 5.0);
        g.draw(shape);
        g.setTransform(oldAt);
    }

    private static void drawScaledObject(Graphics2D g, Shape shape)
    {
        AffineTransform at = AffineTransform.getScaleInstance(5.0, 5.0);
        g.draw(at.createTransformedShape(shape));
    }

}

编辑回应评论

我发布的代码并不“复杂”。它必须复杂,但不会更多。你不应该扩展JFrame,也不应该覆盖paint。您应该在 EDT 上创建 GUI。你应该...

但是,您不应该使用如下代码,但也许这就是您要查找的内容

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.Dimension;

public class Stretch extends JFrame {
    int originalHeight = 600;
    int originalWidth = 600;
    public Stretch() {
        super("Stretch");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(originalWidth, originalHeight);
    }
    public static void main(String[] args) {
        Stretch s = new Stretch();
        s.setVisible(true);
    }
    public void paint(Graphics g) {
        Dimension size = this.getBounds().getSize();
        int rectWidth = 100;
        int rectHeight = 130;

        g.setColor(Color.white);
        g.fillRect(0, 0, size.width, size.height);

        g.setColor(Color.black);

        int w = rectWidth + size.width - originalWidth;
        int h = rectHeight + size.height - originalHeight;
        double sx = (double)w / rectWidth;
        double sy = (double)h / rectHeight;
        double s = Math.min(sx, sy);
        int fw = (int)(s * rectWidth);
        int fh = (int)(s * rectHeight);
        g.drawRect(100, 100, fw, fh);

    }
}

【讨论】:

  • 谢谢,但这对我的目的来说太复杂了,解决方案只是我认为的公式
  • 对不起,你能解释一下为什么我不应该覆盖paint并扩展JFrame吗?谢谢你最后的代码,完美。
  • Why you should not extend JFrameJFrame 是一个复杂的顶层组件,它的paint 方法做了很多内部管理(你可能会看到你的画框在调整框架大小时闪烁。那是因为你覆盖了paint,它可以不再正常工作)。如果你只想画一些东西,你应该使用“最简单的组件”,这将是一个JPanel,你覆盖paintComponent - 如第一个代码sn-p所示。
【解决方案2】:

如何将宽度和高度乘以您想要的比例?

因此,如果您想将其缩放 2:

g.drawRect(100, 100, 2 * (rectWidth + size.width - originalWidth), 2 * (rectHeight + size.height - originalHeight));

【讨论】:

  • 如果您调整窗口大小,绘图应相应地重新缩放
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 2014-11-23
相关资源
最近更新 更多