简体   繁体   中英

java scaled image drawing problems

I searched a bit and also asked more experienced friends but could not find anything. I'm trying to make a recording software with java (eg like fraps,bandicam). Basically it works without problems and even pretty good what I noticed on mistake because I'm making an image every 2 milliseconds and it works good=) the only problem I had was that the image was too big for a little jframe to print on it (of course 1080p screen doesn´t fit on to like 600p frame :/ ) so I tried to scale it with Image.getScaledInstance() but when I print the scaled image it starts to flicker so you see the image for a short period of time (like a half second) and then it's gone. (NOTE: when I use the debugger mode it works pretty much perfect, also I'm aware that the framework in the code isn´t good and im not saving anything yet. I am using the Netbeans IDE).

Code:

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                   
}

the problem is, that you draw the image in your custom function. In swing every component has it's own paint(...) function, that will be called by the framework if the component needs to be redrawn:

So you need to override the paint(...) function in your DisplayFrame class. Save your current Image as class parameter and use it in the overridden paint(...) function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM