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