1 package org.opencv.highgui; 2 3 import org.opencv.core.Mat; 4 5 import javax.swing.*; 6 import java.awt.*; 7 import java.awt.event.KeyEvent; 8 import java.awt.event.KeyListener; 9 import java.awt.image.BufferedImage; 10 import java.awt.image.DataBufferByte; 11 import java.util.HashMap; 12 import java.util.Iterator; 13 import java.util.Map; 14 import java.util.concurrent.CountDownLatch; 15 import java.util.concurrent.TimeUnit; 16 17 /** 18 * This class was designed for use in Java applications 19 * to recreate the OpenCV HighGui functionalities. 20 */ 21 public final class HighGui { 22 23 // Constants for namedWindow 24 public final static int WINDOW_NORMAL = ImageWindow.WINDOW_NORMAL; 25 public final static int WINDOW_AUTOSIZE = ImageWindow.WINDOW_AUTOSIZE; 26 27 // Control Variables 28 public static int n_closed_windows = 0; 29 public static int pressedKey = -1; 30 public static CountDownLatch latch = new CountDownLatch(1); 31 32 // Windows Map 33 public static Map<String, ImageWindow> windows = new HashMap<String, ImageWindow>(); 34 namedWindow(String winname)35 public static void namedWindow(String winname) { 36 namedWindow(winname, HighGui.WINDOW_AUTOSIZE); 37 } 38 namedWindow(String winname, int flag)39 public static void namedWindow(String winname, int flag) { 40 ImageWindow newWin = new ImageWindow(winname, flag); 41 if (windows.get(winname) == null) windows.put(winname, newWin); 42 } 43 imshow(String winname, Mat img)44 public static void imshow(String winname, Mat img) { 45 if (img.empty()) { 46 System.err.println("Error: Empty image in imshow"); 47 System.exit(-1); 48 } else { 49 ImageWindow tmpWindow = windows.get(winname); 50 if (tmpWindow == null) { 51 ImageWindow newWin = new ImageWindow(winname, img); 52 windows.put(winname, newWin); 53 } else { 54 tmpWindow.setMat(img); 55 } 56 } 57 } 58 toBufferedImage(Mat m)59 public static Image toBufferedImage(Mat m) { 60 int type = BufferedImage.TYPE_BYTE_GRAY; 61 62 if (m.channels() > 1) { 63 type = BufferedImage.TYPE_3BYTE_BGR; 64 } 65 66 int bufferSize = m.channels() * m.cols() * m.rows(); 67 byte[] b = new byte[bufferSize]; 68 m.get(0, 0, b); // get all the pixels 69 BufferedImage image = new BufferedImage(m.cols(), m.rows(), type); 70 71 final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 72 System.arraycopy(b, 0, targetPixels, 0, b.length); 73 74 return image; 75 } 76 createJFrame(String title, int flag)77 public static JFrame createJFrame(String title, int flag) { 78 JFrame frame = new JFrame(title); 79 80 frame.addWindowListener(new java.awt.event.WindowAdapter() { 81 @Override 82 public void windowClosing(java.awt.event.WindowEvent windowEvent) { 83 n_closed_windows++; 84 if (n_closed_windows == windows.size()) latch.countDown(); 85 } 86 }); 87 88 frame.addKeyListener(new KeyListener() { 89 @Override 90 public void keyTyped(KeyEvent e) { 91 } 92 93 @Override 94 public void keyReleased(KeyEvent e) { 95 } 96 97 @Override 98 public void keyPressed(KeyEvent e) { 99 pressedKey = e.getKeyCode(); 100 latch.countDown(); 101 } 102 }); 103 104 if (flag == WINDOW_AUTOSIZE) frame.setResizable(false); 105 106 return frame; 107 } 108 waitKey()109 public static void waitKey(){ 110 waitKey(0); 111 } 112 waitKey(int delay)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 destroyWindow(String winname)175 public static void destroyWindow(String winname) { 176 ImageWindow tmpWin = windows.get(winname); 177 if (tmpWin != null) windows.remove(winname); 178 } 179 destroyAllWindows()180 public static void destroyAllWindows() { 181 windows.clear(); 182 } 183 resizeWindow(String winname, int width, int height)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 moveWindow(String winname, int x, int y)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 } 194