gpt4 book ai didi

java - 在没有清晰背景的情况下旋转图像

转载 作者:行者123 更新时间:2023-11-29 05:08:19 25 4
gpt4 key购买 nike

我已经阅读了很多有关绘制图像的文章,但是当我需要保留背景时,我无法使它们起作用。单击 JButton 后,我试图旋转位于另一个图像上方的图像。背景图像是通过以下方式在 JPanel 上生成的:

public void paintComponent(Graphics g){

int index = 0;

Graphics2D g2 = (Graphics2D) g;

super.paintComponent(g);

try {
image = ImageIO.read(url1);
image2 = ImageIO.read(url2);
image3 = ImageIO.read(url3);
} catch (IOException e) {
}


g.drawImage(image, 0, 0, null);
g.drawImage(image3, 0, 0, null);

if(scaleDrawnFlag == 0){

for(index = 0; index < 60; index ++){
tx = AffineTransform.getRotateInstance(Math.toRadians(6*index), this.getHeight()/2, this.getWidth()/2);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
g.drawImage(op.filter(image3, null), 0, 0, null);
}

scaleDrawnFlag = 1;
}

g.drawImage(image2, 0, 0, null);

}

其中进入一个名为JPanel的面板,只绘制一次图像以保持刷新性能,仅针对动画图像。这为转速表绘制了一个刻度,总共 60 行,其中每行都是 image3 的副本

动画图像是通过按下 JButton 生成的,由以下人员制作:

public void paintComponent(Graphics g){

super.paintComponent(g);
BufferedImage img = new BufferedImage(370, 370, BufferedImage.TRANSLUCENT);
Graphics2D g2d = img.createGraphics();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f));
Graphics2D temp = (Graphics2D) g;
tx = AffineTransform.getRotateInstance(Math.toRadians(degrees), this.getHeight()/2, this.getWidth()/2);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
temp.drawImage(op.filter(image2, null), 0, 0, null);
temp.dispose();
}

这是另一个名为 overPanel 的 JPanel,它位于初始 JPanel 之上。

但是,当我调用这些方法时:

public void up(){
degrees ++;
if(degrees == 360) degrees = 0;
repaint();
}

public void down(){
degrees --;
if(degrees == -360) degrees = 0;
repaint();
}

在 overPanel 类上,JPanel 被完全清除。动画运行良好,但背景消失了。

我必须怎么做才能保留背景?

我还尝试了另一种解决方案,即在每次 up() 和 down() 调用时再次绘制 60 条线。背景已重新绘制,但需要花费太多时间才能完成,因此旋转转速表指示器的动画会滞后。

最佳答案

切勿处置 JVM 提供给您的 Graphics 对象。你这样做:

// temp **is** the same object as g and is the Graphics object given by the JVM
Graphics2D temp = (Graphics2D) g;
//....
temp.dispose();

并且不应该这样做,因为它会完全破坏绘画链。相反,您应该处理您创建的 g2d 对象。

另外,这样也行

Graphics2D temp = (Graphics2D) g.create(); // temp **is** a new object
//....
temp.dispose(); // this is OK

其他问题:

  • 我也不会在 paintComponent 中创建我的 BufferedImage,而是将其作为类的一个字段,并在 paintComponent 中显示它。
  • 您的顶级代码显示忽略的关键异常——您不想这样做。
  • 它还展示了在绘画方法中读取图像文件,这会不必要地减慢图形速度。同样,不要这样做,在任何绘画方法之外读入一次图像,存储结果,并在绘画方法中使用它们。
  • paintComponent 方法是protected,而不是public。避免不必要地提高其知名度。

在您的最小示例程序中,您的 scaleDrawnFlag 变量及其关联的 if block 似乎让您感到困惑。该变量和 if block 的目的是什么?如果你摆脱变量和 if block ,你的背景将持续存在。我自己会通过创建稳定的背景图像并每次在 paintComponent(...) 方法中绘制它来做不同的事情。我不会重写 update(...) ,因为那是 AWT 的拼凑而不是用于 Swing 图形。我还尽量避免 null 布局和 setBounds(...) 就像瘟疫一样,因为这会导致非常难以调试、维护和增强的不灵活、僵化的 GUI。例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

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

@SuppressWarnings("serial")
public class MyMainPanel extends JPanel {
private MyDrawingPanel myDrawingPanel;

public MyMainPanel() {
try {
myDrawingPanel = new MyDrawingPanel();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}

JPanel rightPanel = new JPanel();
rightPanel.setLayout(new GridLayout(0, 1, 5, 5));
rightPanel.add(new JButton(new MyUpAction("Up", KeyEvent.VK_U)));
rightPanel.add(new JButton(new MyDownAction("Down", KeyEvent.VK_D)));

JPanel rightWrapPanel = new JPanel(new BorderLayout());
rightWrapPanel.add(rightPanel, BorderLayout.PAGE_START);

setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout());
add(myDrawingPanel, BorderLayout.CENTER);
add(rightWrapPanel, BorderLayout.LINE_END);
}

private class MyUpAction extends AbstractAction {
public MyUpAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}

@Override
public void actionPerformed(ActionEvent e) {
myDrawingPanel.up();
}
}

private class MyDownAction extends AbstractAction {
public MyDownAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}

@Override
public void actionPerformed(ActionEvent e) {
myDrawingPanel.down();
}
}

private static void createAndShowGui() {
JFrame frame = new JFrame("MyMainPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

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

@SuppressWarnings("serial")
class MyDrawingPanel extends JPanel {
private static final String NEEDLE_IMG_PATH = "http://1.bp.blogspot.com/"
+ "-fq-oPGBSLp4/Ttoj7DoAMWI/AAAAAAAABtc/t7gKJlfRQuo/s400/secondHand.png";
private static final String ORANGE_DISK_IMG_PATH = "http://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Circle_Fulvous_Solid.svg/200px-Circle_Fulvous_Solid.svg.png";
private static final String GREEN_LINE_IMG_PATH = "http://www.xtremeskater.com/math/images/circle_radius.png";
private static final int MAX_DEGREES = 360;

private int imgWidth = 0;
private int imgHeight = 0;
private BufferedImage needleImg = null;
private BufferedImage orangeDiskImg = null;
private BufferedImage greenLineImg = null;
private BufferedImage backgroundImg = null;
private int degrees;

public MyDrawingPanel() throws IOException {
URL needleUrl = new URL(NEEDLE_IMG_PATH);
URL orangeDiskUrl = new URL(ORANGE_DISK_IMG_PATH);
URL greenLineUrl = new URL(GREEN_LINE_IMG_PATH);
needleImg = ImageIO.read(needleUrl);
orangeDiskImg = ImageIO.read(orangeDiskUrl);
greenLineImg = ImageIO.read(greenLineUrl);

imgWidth = Math.max(orangeDiskImg.getWidth(),
greenLineImg.getWidth());
imgHeight = Math.max(orangeDiskImg.getHeight(),
greenLineImg.getHeight());
backgroundImg = new BufferedImage(imgWidth, imgHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = backgroundImg.createGraphics();
drawBackground(g2, imgWidth, imgHeight);
g2.dispose();
}

@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(imgWidth, imgHeight);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, null);
}
AffineTransform tx = AffineTransform.getRotateInstance(Math.toRadians(degrees),
this.getHeight() / 2, this.getWidth() / 2);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
g.drawImage(op.filter(needleImg, null), 0, 0, null);
}

public void up() {
degrees++;
degrees %= MAX_DEGREES;
repaint();
}

public void down() {
degrees--;
degrees += MAX_DEGREES;
degrees %= MAX_DEGREES;
repaint();
}

public int getDregrees() {
return degrees;
}

private void drawBackground(Graphics2D g2, int biWidth, int biHeight) {
int index;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(orangeDiskImg, 0, 0, null);
g2.drawImage(greenLineImg, 0, 0, null);
AffineTransform tx = AffineTransform.getRotateInstance(Math.toRadians(6),
biWidth / 2, biHeight / 2);
for (index = 0; index < 60; index++) {
g2.transform(tx);
g2.drawImage(greenLineImg, 0, 0, null);
}
}
}

关于java - 在没有清晰背景的情况下旋转图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29632267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com