001package org.opencv.highgui; 002 003import org.opencv.core.Mat; 004 005import javax.swing.*; 006import java.awt.*; 007import java.awt.event.KeyEvent; 008import java.awt.event.KeyListener; 009import java.awt.image.BufferedImage; 010import java.awt.image.DataBufferByte; 011import java.util.HashMap; 012import java.util.Iterator; 013import java.util.Map; 014import java.util.concurrent.CountDownLatch; 015import java.util.concurrent.TimeUnit; 016 017/** 018 * This class was designed for use in Java applications 019 * to recreate the OpenCV HighGui functionalities. 020 */ 021public final class HighGui { 022 023 // Constants for namedWindow 024 public final static int WINDOW_NORMAL = ImageWindow.WINDOW_NORMAL; 025 public final static int WINDOW_AUTOSIZE = ImageWindow.WINDOW_AUTOSIZE; 026 027 // Control Variables 028 public static int n_closed_windows = 0; 029 public static int pressedKey = -1; 030 public static CountDownLatch latch = new CountDownLatch(1); 031 032 // Windows Map 033 public static Map<String, ImageWindow> windows = new HashMap<String, ImageWindow>(); 034 035 public static void namedWindow(String winname) { 036 namedWindow(winname, HighGui.WINDOW_AUTOSIZE); 037 } 038 039 public static void namedWindow(String winname, int flag) { 040 ImageWindow newWin = new ImageWindow(winname, flag); 041 if (windows.get(winname) == null) windows.put(winname, newWin); 042 } 043 044 public static void imshow(String winname, Mat img) { 045 if (img.empty()) { 046 System.err.println("Error: Empty image in imshow"); 047 System.exit(-1); 048 } else { 049 ImageWindow tmpWindow = windows.get(winname); 050 if (tmpWindow == null) { 051 ImageWindow newWin = new ImageWindow(winname, img); 052 windows.put(winname, newWin); 053 } else { 054 tmpWindow.setMat(img); 055 } 056 } 057 } 058 059 public static Image toBufferedImage(Mat m) { 060 int type = BufferedImage.TYPE_BYTE_GRAY; 061 062 if (m.channels() > 1) { 063 type = BufferedImage.TYPE_3BYTE_BGR; 064 } 065 066 int bufferSize = m.channels() * m.cols() * m.rows(); 067 byte[] b = new byte[bufferSize]; 068 m.get(0, 0, b); // get all the pixels 069 BufferedImage image = new BufferedImage(m.cols(), m.rows(), type); 070 071 final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 072 System.arraycopy(b, 0, targetPixels, 0, b.length); 073 074 return image; 075 } 076 077 public static JFrame createJFrame(String title, int flag) { 078 JFrame frame = new JFrame(title); 079 080 frame.addWindowListener(new java.awt.event.WindowAdapter() { 081 @Override 082 public void windowClosing(java.awt.event.WindowEvent windowEvent) { 083 n_closed_windows++; 084 if (n_closed_windows == windows.size()) latch.countDown(); 085 } 086 }); 087 088 frame.addKeyListener(new KeyListener() { 089 @Override 090 public void keyTyped(KeyEvent e) { 091 } 092 093 @Override 094 public void keyReleased(KeyEvent e) { 095 } 096 097 @Override 098 public void keyPressed(KeyEvent e) { 099 pressedKey = e.getKeyCode(); 100 latch.countDown(); 101 } 102 }); 103 104 if (flag == WINDOW_AUTOSIZE) frame.setResizable(false); 105 106 return frame; 107 } 108 109 public static void waitKey(){ 110 waitKey(0); 111 } 112 113 public static int waitKey(int delay) { 114 // Reset control values 115 latch = new CountDownLatch(1); 116 n_closed_windows = 0; 117 pressedKey = -1; 118 119 // If there are no windows to be shown return 120 if (windows.isEmpty()) { 121 System.err.println("Error: waitKey must be used after an imshow"); 122 System.exit(-1); 123 } 124 125 // Remove the unused windows 126 Iterator<Map.Entry<String, 127 ImageWindow>> iter = windows.entrySet().iterator(); 128 while (iter.hasNext()) { 129 Map.Entry<String, 130 ImageWindow> entry = iter.next(); 131 ImageWindow win = entry.getValue(); 132 if (win.alreadyUsed) { 133 iter.remove(); 134 win.frame.dispose(); 135 } 136 } 137 138 // (if) Create (else) Update frame 139 for (ImageWindow win : windows.values()) { 140 141 if (win.img != null) { 142 143 ImageIcon icon = new ImageIcon(toBufferedImage(win.img)); 144 145 if (win.lbl == null) { 146 JFrame frame = createJFrame(win.name, win.flag); 147 JLabel lbl = new JLabel(icon); 148 win.setFrameLabelVisible(frame, lbl); 149 } else { 150 win.lbl.setIcon(icon); 151 } 152 } else { 153 System.err.println("Error: no imshow associated with" + " namedWindow: \"" + win.name + "\""); 154 System.exit(-1); 155 } 156 } 157 158 try { 159 if (delay == 0) { 160 latch.await(); 161 } else { 162 latch.await(delay, TimeUnit.MILLISECONDS); 163 } 164 } catch (InterruptedException e) { 165 e.printStackTrace(); 166 } 167 168 // Set all windows as already used 169 for (ImageWindow win : windows.values()) 170 win.alreadyUsed = true; 171 172 return pressedKey; 173 } 174 175 public static void destroyWindow(String winname) { 176 ImageWindow tmpWin = windows.get(winname); 177 if (tmpWin != null) windows.remove(winname); 178 } 179 180 public static void destroyAllWindows() { 181 windows.clear(); 182 } 183 184 public static void resizeWindow(String winname, int width, int height) { 185 ImageWindow tmpWin = windows.get(winname); 186 if (tmpWin != null) tmpWin.setNewDimension(width, height); 187 } 188 189 public static void moveWindow(String winname, int x, int y) { 190 ImageWindow tmpWin = windows.get(winname); 191 if (tmpWin != null) tmpWin.setNewPosition(x, y); 192 } 193}