如何在Java中重复操作时从内存中清除图像



我正在为一个新程序而苦苦挣扎。

该程序旨在从网络摄像头获取光谱,并将其与参考光谱进行比较。这是在用户单击一个名为"captureButton"的按钮时完成的。

操作结束时,程序在消息对话框中显示频谱图(通过Scilab通过批处理文件从外部创建(。这一切都如预期的那样完美地发生了。但是,如果再次运行该操作(再次按下按钮(,该过程会正常进行,但消息对话框中显示的图像是上次运行的旧图像。

尽管在操作开始时,所有旧文件都会被擦除,然后使用新数据重新创建,但还是会发生这种情况。

然后我怀疑旧图像是以某种方式存储在内存中的,而不是第二次从新文件中调用。

我尝试过请求垃圾收集器,但没有效果。

这是代码(我已经删除了不相关的片段,因为这是一个相当长的代码(。。。

//Imports etc here
public class VSAWindow extends javax.swing.JFrame {
    public VSAWindow() {
        initComponents();
        //Set defaults for user input
        sampleText.setText("50");
        toleranceText.setText("1");
        acceptanceText.setText("10");
        //Clear Calibration window and set calibration spectrum image
        jLabel10.setText("");
        jLabel11.setText("");
        ImageIcon icon = new ImageIcon("reference/mainspectrum.png");
        jLabel10.setIcon(icon);
    }

        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {
        captureButton = new javax.swing.JButton();
        // Some other declarations...
        jButton1 = new javax.swing.JButton();
        calibrateButton = new javax.swing.JButton();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        captureButton.setText("Capture");
        captureButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                captureButtonActionPerformed(evt);
            }
        });
    //Some code which sets a load of text on screen...
        jButton1.setText("EXIT");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
    jLabel10.setText("jLabel10");
    jLabel11.setText("jLabel11");
    //A load of code added by the IDE for adding various components      
private void captureButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              
    //CLEAR ALL PREVIOUS IF POSSIBLE
    System.gc();
    //Check user input values for validity
    try {
        String smpIn = sampleText.getText();
        String tolIn = toleranceText.getText();
        String accIn = acceptanceText.getText();
        int smpVl = Integer.parseInt(smpIn);
        double tolVl = Integer.parseInt(tolIn);
        int accVl = Integer.parseInt(accIn);
        int stopgo = 0; //Condition variable to prevent invalid operation
        if (smpVl >= 0 && smpVl <= 766 && tolVl >= 0 && tolVl <= 100 && accVl >= 0 && accVl <= 100) {
            stopgo = 1;
        }
        if (stopgo == 1) {//Proceed if input values have been checked for validity
            try {
                //BEFORE BEGINNING CLEAR ALL FILES FROM PREVIOUS RUNS
                //This will prevent old data from being displayed in
                //the event of system slowdown
                File del1 = new File("convert.bat");
                File del2 = new File("inplot.png");
                File del3 = new File("newdata.csv");
                File del4 = new File("peakdata.csv");
                File del5 = new File("peaks.sce");
                File del6 = new File("refbat.bat");
                File del7 = new File("refplot.png");
                File del8 = new File("rgb.sce");
                File del9 = new File("rgbbat.bat");
                File del10 = new File("test.png");
                File del11 = new File("spectra\newspectrum.ppm");
                File del12 = new File("spectra\convspectrum.doc");
                del1.delete();
                del2.delete();
                del3.delete();
                del4.delete();
                del5.delete();
                del6.delete();
                del7.delete();
                del8.delete();
                del9.delete();
                del10.delete();
                del11.delete();
                del12.delete();
                //CAPTURE SPECTRUM IMAGE
                Webcam webcam = Webcam.getDefault();
                Dimension size = new Dimension(640, 480);
                webcam.setViewSize(size);
                webcam.open();
                BufferedImage image = webcam.getImage();
                try {
                    ImageIO.write(image, "PNG", new File("test.png"));
                } catch (IOException ex) {
                    Logger.getLogger(VSAWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
                System.out.println("Obtaining data from spectrometer...");
                //CREATE BATCH FILE FOR IMAGE CONVERSION TO .PPM FORMAT
                String filename = "convert.bat";
                WriteFile data = new WriteFile(filename, false);
                WriteFile dataline = new WriteFile(filename, true);
                data.WriteToFile("cd "C:\Program Files (x86)\IrfanView"");
                dataline.WriteToFile("i_view32.exe C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\test.png /convert=C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\newspectrum.ppm");
                dataline.WriteToFile("exit");
                //Wait for processes to finish...
                File f = new File("test.png");
                int msgCheck = 0;//Variable to prevent repeated i/o
                while (!f.exists()) {
                    if (msgCheck == 0) {
                        System.out.println("Building spectral data...");
                    }
                    msgCheck = 1;
                }
                //Shuts webcam and proceeds as long as input has been obtained
                webcam.close();
                //EXECUTE CONVERSION BATCH FILE
                Runtime.getRuntime().exec("cmd /c start convert.bat");
                //CONVERSION BY TO LINE BY LINE FORMAT - NEEDS STREAMLINING SOMEHOW
                //Wait for file to be created:
                File fn = new File("spectra\newspectrum.ppm");
                int msgCheck2 = 0;//Variable to prevent repeated i/o
                while (!fn.exists()) {
                    if (msgCheck2 == 0) {
                        System.out.println("Performing file operations....");
                    }
                    msgCheck2 = 1;
                }//Proceeds once file has been converted and placed in 'spectra' folder
                //Open file for format conversion
                ReadFile open = new ReadFile("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\newspectrum.ppm");
                String[] readLines;
                readLines = open.OpenFile();
                //Prepare Writefile
                WriteFile begin = new WriteFile("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\convspectrum.doc", false);
                begin.WriteToFile("");
                //Create file append code
                WriteFile write = new WriteFile("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\convspectrum.doc", true);
                //Begin looping and adding to new file
                String columns = readLines[2].split("\ ")[0];
                int nos = Integer.parseInt(columns);
                for (int i = 0; i < readLines.length; i++) {
                    if (i < 4) {
                        write.WriteToFile(readLines[i]);
                    } else if (i == 2) {
                        //Splits condensed data and rebuilds as line-by-line format
                    } else if (i >= 4 && i < nos) {
                        String[] lnMk = readLines[i].split("[\W]");
                        for (int j = 0; j < lnMk.length; j++) {
                            write.WriteToFile(lnMk[j]);
                        }
                    }
                }
                //BEGIN DATA ANALYSIS
                //FILE READING PROCEDURE
                ReadFile file = new ReadFile("spectra/convspectrum.doc");//Read in filename to be opened
                String aryLines[];//Declare string array for file contents in line by line read
                aryLines = file.OpenFile();//Read file line by line and assign each line to a sequential array index
                //DECLARE VARIABLES
                String beforeSpc = aryLines[3].split("\ ")[0];
                System.out.println("Number of columns = " + beforeSpc);
                int docWidth = Integer.parseInt(beforeSpc);//Gets spectrum width from file header
                int rgbCount = 0;//Index for counting final RGB indices
                int sample = smpVl;//Declares lower limit for sampling (Sample = r+g+b)(min=0, max = 765)
                String[] rgbArray = new String[aryLines.length];//Declare array for storage of final RGB values
                //CREATE CSV FILE FOR SCILAB - INPUT SPECTRUM
                WriteFile newData = new WriteFile("newdata.csv", false);
                newData.WriteToFile("");
                //CREATE SCILAB SCRIPT FILE - INPUT SPECTRUM
                WriteFile createSciRGB = new WriteFile("rgb.sce", false);
                createSciRGB.WriteToFile("");
                //CONFIGURE SCILAB SCRIPT FOR RGB DATA - INPUT SPECTRUM
                WriteFile addSciRGB = new WriteFile("rgb.sce", true);
                addSciRGB.WriteToFile("cd("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser");");
                addSciRGB.WriteToFile("y = evstr(read_csv("newdata.csv"));");
                addSciRGB.WriteToFile("xlabel("Wavelength (nm)")");
                addSciRGB.WriteToFile("ylabel("Intesity (Combined RGB Value)")");
                addSciRGB.WriteToFile("plot2d(y)");
                addSciRGB.WriteToFile("xs2png(0, "inplot.png" )");
                addSciRGB.WriteToFile("exit");
                //CREATE BATCH FILE FOR RUNNING SCILAB (RGB INPUT SPECTRUM)
                WriteFile rgbBat = new WriteFile("rgbbat.bat", false);
                rgbBat.WriteToFile(""C:/Program Files/scilab-5.5.0/bin/Scilex.exe" scilab-adv-cli -f "rgb.sce" -nw");
                WriteFile addRgbBat = new WriteFile("rgbbat.bat", true);
                addRgbBat.WriteToFile("exit");
                //BEGIN LOOPING THROUGH INPUT FILE
                for (int i = 0; i < 3 * docWidth; i++) {//Restricts loop to single line by stopping after 1x width of sample spectrum
                    //System.out.println(aryLines[i]);
                    if (i >= 6 && i % 3 == 0) {
                        //ASSIGN R,G,B VALUES
                        int r = Integer.parseInt(aryLines[i - 2]);
                        int g = Integer.parseInt(aryLines[i - 1]);
                        int b = Integer.parseInt(aryLines[i]);
                        int dataR = Integer.parseInt(aryLines[i - 2]);
                        int dataG = Integer.parseInt(aryLines[i - 1]);
                        int dataB = Integer.parseInt(aryLines[i]);
                        int lineSpec = dataR + dataG + dataB;
                        String dataPoint = Integer.toString(lineSpec);
                        //ADD RGB DATA TO SCILAB FILE - INPUT SPECTRUM
                        WriteFile peaks = new WriteFile("newdata.csv", true);
                        peaks.WriteToFile(dataPoint);
                        int pixSum = r + g + b;//Creates measure of pixel significance
                        if (pixSum > sample) {
                            rgbArray[rgbCount] = aryLines[i - 2] + " " + aryLines[i - 1] + " " + aryLines[i];
                            rgbCount++;
                        }
                    }
                }
                //OUTPUT ARRAY OF FINAL RGB VALUES
                for (int j = 0; j < rgbArray.length; j++) {
                    if (rgbArray[j] != null) {
                        System.out.println(rgbArray[j]);
                    }
                }
        //END COLLECTION OF INPUT DATA
                //BEGIN CREATION OF COMPARISON DATA
                //FILE READING PROCEDURE FOR REFERENCE SPECTRUM
                ReadFile specFile = new ReadFile("reference/mainspectrum.ppm");//Read in filename to be opened
                String specLines[];//Declare string array for file contents in line by line read
                specLines = specFile.OpenFile();//Read file line by line and assign each line to a sequential array index
                //DECLARE VARIABLES
                String specBeforeSpc = specLines[2].split("\ ")[0];//Gets spectrum width from file header
                System.out.println("Number of columns = " + specBeforeSpc);
                int specWidth = Integer.parseInt(specBeforeSpc);
                int specCount = 0;//Index for counting reference RGB indices
                String[] specArray = new String[specWidth];//Declare array for storage of reference RGB values
                //CREATE CSV FILE FOR SCILAB - REFERENCE SPECTRUM
                WriteFile stFile = new WriteFile("peakdata.csv", false);//Creates and clears file for line spectrum data
                stFile.WriteToFile("");
                //CREATE SCILAB SCRIPT FILE - REFERENCE SPECTRUM
                WriteFile createSciSpec = new WriteFile("peaks.sce", false);
                createSciSpec.WriteToFile("");
                //CONFIGURE SCILAB SCRIPT FOR RGB DATA - REFERENCE SPECTRUM
                WriteFile addSciSpec = new WriteFile("peaks.sce", true);
                addSciSpec.WriteToFile("cd("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser");");
                addSciSpec.WriteToFile("y = evstr(read_csv("peakdata.csv"));");
                addSciSpec.WriteToFile("xlabel("Wavelength (nm)")");
                addSciSpec.WriteToFile("ylabel("Intesity (Combined RGB Value)")");
                addSciSpec.WriteToFile("plot2d(y)");
                addSciSpec.WriteToFile("xs2png(0, "refplot.png" )");
                addSciSpec.WriteToFile("exit");
                //CREATE BATCH FILE FOR RUNNING SCILAB (REFERENCE SPECTRUM)
                WriteFile refBat = new WriteFile("refbat.bat", false);
                refBat.WriteToFile(""C:/Program Files/scilab-5.5.0/bin/Scilex.exe" scilab-adv-cli -f "peaks.sce" -nw");
                WriteFile addRefBat = new WriteFile("refbat.bat", true);
                addRefBat.WriteToFile("exit");
                //BEGIN LOOPING THROUGH SPECTRUM REFERENCE FILE
                for (int i = 0; i < 3 * specWidth; i++) {//Restricts loop to single line by stopping after 1x width of reference spectrum
                    //Eliminate header and compress RGB lines into single, 3 point entries
                    if (i >= 6 && i % 3 == 0) {
                        //ASSIGN R,G,B VALUES TO REFERENCE SPECTRUM ARRAY
                        specArray[specCount] = specLines[i - 2] + " " + specLines[i - 1] + " " + specLines[i];
                        specCount++;
                        int dataR = Integer.parseInt(specLines[i - 2]);
                        int dataG = Integer.parseInt(specLines[i - 1]);
                        int dataB = Integer.parseInt(specLines[i]);
                        int lineSpec = dataR + dataG + dataB;
                        String dataPoint = Integer.toString(lineSpec);
                        //ADD DATA TO SCILAB FILE - REFERENCE SPECTRUM
                        WriteFile peaks = new WriteFile("peakdata.csv", true);
                        peaks.WriteToFile(dataPoint);
                    }
                }
                System.out.println("Reference Spectrum Obtained");
                //COMPARE INPUT AND REFERENCE SPECTRA
                //Set matching tolerance:
                double tol = (765 / 100) * tolVl;
                //Set lower threshold for partial matches
                int disp = 100 - accVl;
                //Find length of input RGB input array to prevent null pointers
                int rgbLength = 0;
                //Declare null variables for match counts
                int matchCount = 0;
                int perfCount = 0;
                int possCount = 0;
                //Determine length of RGB Input data array
                for (int x = 0; x < rgbArray.length; x++) {
                    if (rgbArray[x] != null) {
                        rgbLength++;
                    }
                }
                //BEGIN COMPARISON
                //Check each input RGB value...
                for (int l = 0; l < rgbLength; l++) {
                    String[] colours = rgbArray[l].split(" ");
                    String sred = colours[0];
                    String sgreen = colours[1];
                    String sblue = colours[2];
                    int red = Integer.parseInt(sred);
                    int green = Integer.parseInt(sgreen);
                    int blue = Integer.parseInt(sblue);
                    //...against each reference value
                    for (int m = 0; m < specArray.length - 2; m++) {
                        String[] cols = specArray[m].split(" ");
                        String sr = cols[0];
                        String sg = cols[1];
                        String sb = cols[2];
                        int r = Integer.parseInt(sr);
                        int g = Integer.parseInt(sg);
                        int b = Integer.parseInt(sb);
                        double wavelength = 380 + m / 3;
                        //Identify perfect matches
                        if (red == r && green == g && blue == b) {
                            perfCount++;
                            matchCount++;
                            System.out.println("PERFECT MATCH! Found at " + m + " of reference and " + l + " of input");
                           //Some code to output results
                            //Identify imperfect matches based on tolerance
                        } else if (red - r < tol && green - g < tol && blue - b < tol && red - r > -tol && green - g > -tol && blue - b > -tol) {
                            //Calculate possible matches regardless of parameters
                            possCount++;
                            //CALCULATE MATCH QUALITY
                            //Initialise variables
                            double rperc = 100;
                            double gperc = 100;
                            double bperc = 100;
                            double tperc = 100;
                            //Provide conditions
                            if (red > r) {
                                rperc = (100 / (double) red) * (double) r;
                            } else if (red < r) {
                                rperc = (100 / (double) r) * (double) red;
                            }
                            if (green > g) {
                                gperc = (100 / (double) green) * (double) g;
                            } else if (green < g) {
                                gperc = (100 / (double) g) * (double) green;
                            }
                            if (blue > b) {
                                bperc = (100 / (double) blue) * (double) b;
                            } else if (blue < b) {
                                bperc = (100 / (double) b) * (double) blue;
                            }
                            //Small discrepancies involving zero values are automatically given a 95% quality rating
                            if (r == 0 || red == 0) {
                                rperc = 95;
                            }
                            if (g == 0 || green == 0) {
                                gperc = 95;
                            }
                            if (b == 0 || blue == 0) {
                                bperc = 95;
                            }
                            if (red == r) {
                                rperc = 100;
                            }
                            if (green == g) {
                                gperc = 100;
                            }
                            if (blue == b) {
                                bperc = 100;
                            }
                            double tot = (tperc / 300) * (rperc + gperc + bperc);
                            //Check whether available matches are within specified range
                            if (tot > disp) {
                                matchCount++;
                                //Display Match parameters
                                System.out.println("Partial MATCH! Found at " + m + " of reference and " + l + " of input");
                                //Some more code to output results
                                //Calculate and display final quality value and breakdown
                                System.out.println("Match Quality: " + tot + "% (R: " + rperc + " G: " + gperc + " B: " + bperc);
                            }
                        }
                    }
                }
                //More results
                //CHECK THAT BATCH FILES FOR PLOTTING EXIST
                File chkrgb = new File("rgbbat.bat");
                File chkref = new File("refbat.bat");
                while (!chkrgb.exists()) {
                    //Do nothing, just wait
                }
                while (!chkref.exists()) {
                    //Do nothing, just wait
                }
                //PRODUCE SCILAB PLOTS FOR BOTH REFERENCE AND INPUT SPECTRA
                Runtime.getRuntime().exec("cmd /c start refbat.bat");
                Runtime.getRuntime().exec("cmd /c start rgbbat.bat");
                //CHECK PNG PLOTS HAVE BEEN GENERATED
                File chkrgbpng = new File("inplot.png");
                File chkrefpng = new File("refplot.png");
                while (!chkrgbpng.exists()) {
                    System.out.println("Loading RGB Plot...");
                    Thread.sleep(2000);
                }
                while (!chkrefpng.exists()) {
                    System.out.println("Loading Reference Plot...");
                    Thread.sleep(2000);
                }
                //PLACE RGB PLOT IN WINDOW
                System.out.println("Setting plot to screen...");
                ImageIcon icon2 = new ImageIcon("inplot.png");
                String msgTitle = "";
                String msgCaption = "Wavelength in nm";
                JOptionPane.showMessageDialog(null, msgCaption, msgTitle, JOptionPane.INFORMATION_MESSAGE, icon2);
            } catch (IOException ex) {
                Logger.getLogger(VSAWindow.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            JOptionPane.showMessageDialog(null, "Please select valid input values!");
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}                                             
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    System.exit(0);
}                                        
/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    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(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>
    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new VSAWindow().setVisible(true);
        }
    });
}
// Variables declaration - do not modify                     
// End of variables declaration                   
}

有问题的图像是"icon2",位于代码末尾附近,注释"//在窗口中放置RGB绘图"下方,即:

                System.out.println("Setting plot to screen...");
                ImageIcon icon2 = new ImageIcon("inplot.png");
                String msgTitle = "";
                String msgCaption = "Wavelength in nm";
                JOptionPane.showMessageDialog(null, msgCaption, msgTitle, JOptionPane.INFORMATION_MESSAGE, icon2);

我在Windows8.1上的Netbeans 8中工作。

为什么系统会记住上一次运行中的图像,我该如何停止?

非常感谢,并对代码的长度表示歉意,我不想遗漏任何可能导致此问题的内容。如果我能以任何方式改进这个问题,请让我知道,这样我就可以防止自己被屏蔽!

首选的解决方案是使用ImageIO.read而不是ImageIcon(String),但如果必须这样做,则应在尝试重新加载之前调用icon2.flush()

有关更多详细信息,请参阅Image#flush和读取/加载图像

相关内容

  • 没有找到相关文章

最新更新