【问题标题】:How to horizontaly flip graphics in paintComponent? java如何在paintComponent中水平翻转图形?爪哇
【发布时间】:2017-08-18 13:15:24
【问题描述】:

在JPanel 的paintComponent 方法中,我正在使用Graphics 绘制图像,但是我需要水平翻转,并且翻转需要在该方法中进行。我该怎么做?

RoosterB 是 Rooster 的子代,而 Rooster 是 JPanel 的子代。

public class RoosterB extends Rooster
{
    public RoosterB()
    {

    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        // Red stuff
        g.setColor(new Color(56, 118, 29));
        g.drawLine(6, 0, 11, 0);
        g.drawLine(9, 1, 13, 1);
        g.drawLine(8, 2, 9, 2);
        g.drawLine(12, 2, 13, 2);
        g.drawLine(12, 5, 12, 7);
        g.drawLine(13, 5, 13, 9);
        g.drawLine(14, 4, 14, 8);

        g.drawLine(5, 23, 5, 23);
        g.drawLine(8, 24, 8, 24);

        // Beak
        g.setColor(new Color(241, 194, 50));
        g.drawLine(13, 5, 14, 5);
        g.drawLine(13, 7, 15, 7);

        // Eye
        g.setColor(Color.BLACK);
        g.drawLine(10, 3, 10, 4);
        g.setColor(new Color(147,196,125));
        g.drawLine(11, 3, 11, 4);

        // Wing
        g.setColor(new Color(102, 102, 102));
        g.drawLine(0, 12, 0, 13);
        g.drawLine(1, 12, 1, 15);
        g.drawLine(2, 13, 2, 16);
        g.drawLine(3, 13, 9, 13);
        g.drawLine(3, 14, 8, 14);
        g.drawLine(3, 15, 7, 15);
        g.drawLine(7, 12, 8, 12);
        g.drawLine(8, 11, 8, 11);
        g.drawLine(10, 11, 10, 12);
        g.setColor(Color.BLACK);
        g.drawLine(3, 16, 6, 16);
        g.drawLine(8, 15, 8, 15);
        g.drawLine(9, 14, 9, 14);
        g.drawLine(10, 13, 10, 13);

        // Feet
        g.setColor(new Color(147,196,125));
        g.drawLine(5, 24, 5, 25);
        g.drawLine(8, 25, 8, 25);
        g.setColor(new Color(56, 118, 29));
        g.drawLine(4, 26, 6, 26);
        g.drawLine(5, 27, 5, 27);
        g.drawLine(8, 26, 8, 28);
        g.drawLine(7, 27, 9, 27);
    }
}

【问题讨论】:

  • 你能用paintComponent 发布minimal reproducible example 吗?
  • 使用 gimp 或类似程序翻转图像,然后加载其中一个。
  • @c0der 更有帮助吗?
  • @Lowenstein,它是如何完成的?我们无法编译或执行代码。

标签: java graphics rotation flip


【解决方案1】:

我认为这更接近于 MCVE:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class APanel extends JPanel{

    private Line2D line;

    APanel(){

        setPreferredSize(new Dimension(600,400));
        line = new Line2D.Double(50,100, 500,250);
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(Color.BLACK);
        g2d.draw(line);
    }

    public static void main(String[] args){

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel panel = new APanel();
        frame.getContentPane().add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

不是吗?
使用它可以简化问题和答案:

public class APanel extends JPanel{

    double x1 = 50, y1 = 100, x2 = 500, y2 = 250; //line ends
    double fx1, fx2, fy1, fy2; // fliped line ends
    boolean flip = false;

    APanel(){
        setPreferredSize(new Dimension(600,400));
        JButton flipBtn = new JButton("Flip");
        flipBtn.setPreferredSize(new Dimension(100,30));
        flipBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                flip = ! flip;
                repaint();
            }
        });
        add(flipBtn);
        calculteFlipedLine();
    }

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(Color.BLACK);

        if(flip) {
            g2d.draw(new Line2D.Double(x1, y1, x2, y2));
        } else {
            g2d.draw(new Line2D.Double(fx1, fy1, fx2, fy2));
        }
    }

    public static void main(String[] args){

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel panel = new APanel();
        frame.getContentPane().add(panel);

        frame.pack();
        frame.setVisible(true);
    }

    private void calculteFlipedLine() {
        //the calculation here is for simplified
        //horizontal flip. It may vary according to how you
        //define flip
        fx1 = x2; fy1 = y1;
        fx2 = x1; fy2 = y2;
    }
}

【讨论】:

    【解决方案2】:

    对于水平翻转,left <-> right,您正在修改 x 坐标。一般的方式是

    x_new = 2 * x_axis - x_old
    

    这里的x_axis 是“翻转”应该是“环绕”的 x 坐标。例如,如果您想绘制两个相互面对的镜像,则选择一个完全向左或向右的x_axis,然后绘制两次:一次翻转一次,一次不翻转。

    要在 Java 中实现这一点,您应该将所有坐标放入一个数组中。这称为显示列表。然后用循环画出来:

    static struct MyLine {
      int x0, y0, x1, y1;
      Color color;
      MyLine(int x0, int y0, int x1, int y1, Color color) {
        this.x0 = x0; this.y0 = y0; this.x1 = x1; this.y1 = y1;
        this.color = color;
      }
    }
    
    static final Color MY_RED = new Color(56, 118, 29);
    static final Color MY_BEAK_COLOR = ...
    
    static final MyLine [] displayList = {
      new MyLine(6, 0, 11, 0, MY_RED);
      ...
    };
    

    现在在 paintComponent 中,无论是否使用翻转渲染:

    ...
    if (flipped) {
      int o = 2 * x_axis;
      for (MyLine line : displayList) {
        g.setColor(line.color);
        g.drawLine(o - line.x0, line.y0, o - line.x1, line.y1);
      }
    } else {
      for (MyLine line : displayList) {
        g.setColor(line.color);
        g.drawLine(line.x0, line.y0, line.x1, line.y1);
      }
    }
    

    当flip 为真时,你会得到翻转的图像,否则正常。如果两者都需要,请删除if。显示列表的一个优点是您可以在不同版本中多次绘制图像组件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-22
      • 2018-01-17
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多