java缩放图像绘制问题
Posted
技术标签:
【中文标题】java缩放图像绘制问题【英文标题】:java scaled image drawing problems 【发布时间】:2017-08-13 12:19:05 【问题描述】:我搜索了一下,也问了更有经验的朋友,但没有找到任何东西。我正在尝试用java制作录音软件(例如fraps,bandicam)。基本上它可以正常工作,甚至非常好我注意到错误因为我每 2 毫秒制作一张图像并且效果很好=)我遇到的唯一问题是图像太大而无法在上面打印一个小 jframe (当然 1080p 屏幕不适合 600p 帧:/)所以我尝试使用 Image.getScaledInstance() 对其进行缩放,但是当我打印缩放后的图像时,它开始闪烁,因此您可以在短时间内看到图像时间(比如半秒)然后它就消失了。 (注意:当我使用调试器模式时,它工作得非常完美,而且我知道代码中的框架并不好,我还没有保存任何东西。我正在使用 Netbeans IDE)。
代码:
package Main;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Lucas
*/
public class MainClass
private DisplayFrame DF;
private boolean isRecOn;
private int counter = 0;
private BufferedImage[] images;
public void MainClass()
DF = new DisplayFrame(this);
DF.setVisible(true);
/**
*
*/
public void on_offRec(boolean on_off)
this.isRecOn = on_off;
if(on_off == true)
try
this.doRecording();
catch (AWTException ex)
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
private void doRecording() throws AWTException
Robot robo = new Robot();
BufferedImage bi = this.giveAFrame(robo);
boolean changeDisplay = DF.changeDisplay(bi);
if(changeDisplay == true)
Timer timy = new Timer();
TimerTask tt = new TimerTask()
@Override
public void run()
try
doRecording();
catch (AWTException ex)
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
;
timy.schedule(tt, 2);
this.counter = this.counter +1;
private BufferedImage giveAFrame(Robot robo)
Dimension rectt = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle rect = new Rectangle(rectt.width,rectt.height);
BufferedImage createScreenCapture = robo.createScreenCapture(rect);
return createScreenCapture;
/**
* @param args the command line arguments
*/
public static void main(String[] args)
MainClass mc = new MainClass();
mc.MainClass();
package Main;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
/**
*
* @author Lucas
*/
public class DisplayFrame extends javax.swing.JFrame
private boolean isRecOn = false;
private Object recall;
/**
* Creates new form DisplayFrame
*/
public DisplayFrame(Object returner)
initComponents();
recall = returner;
this.getRootPane().addComponentListener(new ComponentAdapter()
public void componentResized(ComponentEvent e)
// This is only called when the user releases the mouse button.
IGotResized(e);
);
private void IGotResized(ComponentEvent e)
System.out.println("Testification rezised msg");
public boolean changeDisplay(BufferedImage bi)
Graphics g = this.getGraphics();
Image i = bi.getScaledInstance(this.getWidth() - 20, this.getHeight() - jButton1.getX() - 10, Image.SCALE_FAST);
g.drawImage(i,0 + 20 , 0+20, this);
return isRecOn;
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents()
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Start/Stop");
jButton1.addActionListener(new java.awt.event.ActionListener()
public void actionPerformed(java.awt.event.ActionEvent evt)
jButton1ActionPerformed(evt);
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addContainerGap(434, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap(353, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap())
);
pack();
// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
// TODO add your handling code here:
if (isRecOn == true)
isRecOn = false;
else
isRecOn = true;
((MainClass)(recall)).on_offRec(isRecOn);
/**
* @param args the command line arguments
*/
public static void main(String args[])
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
if ("Nimbus".equals(info.getName()))
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
catch (ClassNotFoundException ex)
java.util.logging.Logger.getLogger(DisplayFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (InstantiationException ex)
java.util.logging.Logger.getLogger(DisplayFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (IllegalAccessException ex)
java.util.logging.Logger.getLogger(DisplayFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
catch (javax.swing.UnsupportedLookAndFeelException ex)
java.util.logging.Logger.getLogger(DisplayFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//</editor-fold>
/* Create and display the form */
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
// End of variables declaration
【问题讨论】:
【参考方案1】:问题是,您在自定义函数中绘制图像。在 swing 中,每个组件都有自己的 paint(...)
函数,如果需要重绘组件,框架会调用该函数:
因此,您需要在 DisplayFrame
类中覆盖 paint(...)
函数。将您当前的 Image 保存为类参数并在覆盖的 paint(...)
函数中使用它。
【讨论】:
问题在于缩放,如果我评价它可以正常工作:/ 不,问题是,您的 JFrame 决定(不知道为什么)在您绘制图像后重绘,这就是为什么您可以暂时看到您的图像,但在它调用paint(...)
之后再次 JFrame,您的图像消失了。您能否在应用了我的建议后显示您的代码,但没有成功?以上是关于java缩放图像绘制问题的主要内容,如果未能解决你的问题,请参考以下文章