java缩放图像绘制问题

时间:2017-08-13 12:19:06

标签: java image swing recording

我搜索了一下,还问了更多有经验的朋友,却找不到任何东西。我正在尝试使用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 个答案:

答案 0 :(得分:0)

问题是,您在自定义函数中绘制图像。在swing中,每个组件都有自己的paint(...)函数,如果需要重新绘制组件,框架将调用它:

因此,您需要覆盖paint(...)课程中的DisplayFrame功能。将当前Image保存为类参数,并在重写的paint(...)函数中使用它。