Java 旋转球会失去锐度和颜色

Java 旋转球会失去锐度和颜色,java,image,swing,java-2d,Java,Image,Swing,Java 2d,正如你所看到的,我旋转的网球松开了他的形状和颜色。似乎颜色也在旋转。 为什么?有没有办法防止这种情况?我发布了生成上述对话框的代码 谢谢你的帮助。所以有很多问题 在单个步骤中缩放图像永远都不是一个好主意,除非您仅缩放50%。Java在这方面也不是特别擅长。您可以使用一些技巧,例如使用示例中演示的多步缩放或使用外部库,如。有关更多详细信息,请参阅。 您应该避免对同一图像多次应用效果,这只会使更改复杂化,并会降低图像质量。取而代之的是,尽可能地将主图像保持在与原始图像尽可能接近的位置并使用它,以便始

正如你所看到的,我旋转的网球松开了他的形状和颜色。似乎颜色也在旋转。 为什么?有没有办法防止这种情况?我发布了生成上述对话框的代码

谢谢你的帮助。

所以有很多问题

在单个步骤中缩放图像永远都不是一个好主意,除非您仅缩放50%。Java在这方面也不是特别擅长。您可以使用一些技巧,例如使用示例中演示的多步缩放或使用外部库,如。有关更多详细信息,请参阅。 您应该避免对同一图像多次应用效果,这只会使更改复杂化,并会降低图像质量。取而代之的是,尽可能地将主图像保持在与原始图像尽可能接近的位置并使用它,以便始终从相同的起点开始。 Swing不是线程安全的。这意味着三件事。首先,您不应该在事件调度线程的上下文中做任何可能阻止它的事情,比如无限循环。第二,您应该只在EDT上下文中更改UI组件的状态,第三,您应该确保您是在EDT上下文中创建UI的。有关更多详细信息,请参阅和。。。 在默认渲染设置下,除了直线、水平线或垂直线之外的任何东西都会看起来很普通。您需要提供一些渲染提示来增强效果 这就引出了一个问题:如何在Swing中制作动画?好的,您有两个基本选项,您可以使用某种线程,这需要您手动将更新同步回EDT,或者您可以使用Swing javax.Swing.Timer,它允许您以固定的间隔安排在EDT上下文中触发的回调。查看更多详细信息

 package testIDE;

import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import Utils.MyJFrame;

public class ExampleClass {

    public static void main(String[] args) {
        JFrame ballRotate = new BallRotate();
    }
}

class BallRotate extends MyJFrame {

    ArrayList<Integer> degree = new ArrayList<Integer>();
    BufferedImage backGroundImage = getBufferedImage("testIDE/buttonDefaultImage.jpg");
    JLabel backGroundLabel = new JLabel(new ImageIcon(backGroundImage));
    BufferedImage footballImage = getBufferedImage("testIDE/Tennis_Ball.png");
    int x = 0;

    public BallRotate() {

        footballImage=getScaledImage(250, 250, footballImage);
        BufferedImage rotatedImage = footballImage;

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridBagLayout());

        setLabel();
        add(backGroundLabel);

        pack();
        centeringWindow();
        setVisible(true);

        setArray();

        while (true) {
            setDelay(60);
            rotatedImage = rotateImage(rotatedImage, x);

            setMyFuckingLabel(rotatedImage);
            x += 10;
            if (x == 10000) {
                break;
            }
        }
    }

    private void setArray() {
        for (int i = 0; i <= 360; i += 40) {
            degree.add(i);
        }
    }

    private void setLabel() {
        JPanel footBallPanel = new JPanel(new BorderLayout());
        JLabel footBallLabel = new JLabel(new ImageIcon(footballImage));

        footBallPanel.add(footBallLabel);

        borderingJPanel(footBallPanel, null, null); 

        backGroundLabel.setLayout(new GridBagLayout());
        backGroundLabel.add(footBallPanel);
    }

    private BufferedImage rotateImage(BufferedImage buffImage, int degree) {
        BufferedImage rotatedImage = null;

        AffineTransform affineTransform = AffineTransform.getRotateInstance(
                Math.toRadians(15*Math.PI), buffImage.getWidth() / 2,
                buffImage.getHeight() / 2);
        System.out.println(degree*Math.toRadians(1));       
        rotatedImage = new BufferedImage(buffImage.getWidth(),
                buffImage.getHeight(), buffImage.getType());
        Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
        g.setTransform(affineTransform);
        g.drawImage(buffImage, 0, 0, null);
        return rotatedImage;
    }

    public void setMyLabel(BufferedImage rotatedBuffImage) {
        JLabel backgroundlabel = (JLabel) getContentPane().getComponent(0);
        JPanel footBallPanel = (JPanel) backgroundlabel.getComponent(0);
        JLabel footBallLabel = (JLabel) footBallPanel.getComponent(0);

        footBallLabel.setIcon(new ImageIcon(rotatedBuffImage));
    }
}

查看渲染hintsa,您可以看到…-我一定错过了什么。请准确描述你的问题是什么,对于我们这些看不到问题的人来说。另外,不要一直旋转旋转的图像,因为你在合成效果,而是始终旋转主图像我只是想说,你在BallRotate JFrame类中的循环吓坏了我。这要么在它自己的线程中,要么在一个摆动计时器中。你的线程在哪里?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class BallRotate {

    public static void main(String[] args) {
        new BallRotate();
    }

    public BallRotate() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage master;
        private JLabel ball;

        private BufferedImage rotatedImage;
        private float angle = 0;
        private float delta = 5;

        public TestPane() {
            setLayout(new GridBagLayout());
            try {
                master = ImageIO.read(getClass().getResource("/Ball.png"));
                master = getScaledInstanceToFit(master, new Dimension(250, 250));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            ImageIcon icon = new ImageIcon(getRotatedImage(0));
            ball = new JLabel(icon);
            add(ball);

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += delta;
//                    ball.setIcon(new ImageIcon(getRotatedImage(delta)));
                    getRotatedImage(angle);
                    ball.repaint();
                    System.out.println(angle);
                }
            });

            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    timer.start();
                }

            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        protected BufferedImage getRotatedImage(float degree) {

            if (rotatedImage == null) {
                rotatedImage = new BufferedImage(master.getWidth(),
                                master.getHeight(), BufferedImage.TYPE_INT_ARGB);
            }

            AffineTransform affineTransform = AffineTransform.getRotateInstance(
                            Math.toRadians(degree), rotatedImage.getWidth() / 2,
                            rotatedImage.getHeight() / 2);

            Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
            g.setBackground(new Color(255, 255, 255, 0));
            g.clearRect(0, 0, rotatedImage.getWidth(), rotatedImage.getHeight());
            g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
            g.setTransform(affineTransform);
            g.drawImage(master, 0, 0, null);
            g.dispose();

            return rotatedImage;
        }
    }

    public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {

        return getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);

    }

    protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {

        BufferedImage imgScale = img;

        int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
        int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);

//        System.out.println("Scale Size = " + iImageWidth + "x" + iImageHeight);
        if (dScaleFactor < 1.0d) {

            imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);

        }

        return imgScale;

    }

    protected static BufferedImage getScaledDownInstance(BufferedImage img,
                    int targetWidth,
                    int targetHeight,
                    Object hint,
                    boolean higherQuality) {

        int type = (img.getTransparency() == Transparency.OPAQUE)
                        ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = (BufferedImage) img;

        if (targetHeight > 0 || targetWidth > 0) {

            int w, h;
            if (higherQuality) {
                // Use multi-step technique: start with original size, then
                // scale down in multiple passes with drawImage()
                // until the target size is reached
                w = img.getWidth();
                h = img.getHeight();
            } else {
                // Use one-step technique: scale directly from original
                // size to target size with a single drawImage() call
                w = targetWidth;
                h = targetHeight;
            }

            do {
                if (higherQuality && w > targetWidth) {
                    w /= 2;
                    if (w < targetWidth) {
                        w = targetWidth;
                    }
                }

                if (higherQuality && h > targetHeight) {
                    h /= 2;
                    if (h < targetHeight) {
                        h = targetHeight;
                    }
                }

                //            if (w <= 0) w = 1;
                //            if (h <= 0) h = 1;
                BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
                Graphics2D g2 = tmp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
                g2.drawImage(ret, 0, 0, w, h, null);
                g2.dispose();

                ret = tmp;

            } while (w != targetWidth || h != targetHeight);

        } else {

            ret = new BufferedImage(1, 1, type);

        }

        return ret;

    }

    public static double getScaleFactor(int iMasterSize, int iTargetSize) {

        return (double) iTargetSize / (double) iMasterSize;

    }

    public static double getScaleFactorToFit(Dimension original, Dimension toFit) {

        double dScale = 1d;

        if (original != null && toFit != null) {

            double dScaleWidth = getScaleFactor(original.width, toFit.width);
            double dScaleHeight = getScaleFactor(original.height, toFit.height);

            dScale = Math.min(dScaleHeight, dScaleWidth);

        }

        return dScale;

    }

    public static double getScaleFactorToFit(BufferedImage img, Dimension size) {

        double dScale = 1;

        if (img != null) {

            int imageWidth = img.getWidth();
            int imageHeight = img.getHeight();

            dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);

        }

        return dScale;

    }

    public static BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) {

        double scaleFactor = getScaleFactorToFit(img, size);

        return getScaledInstance(img, scaleFactor);

    }

}