package com.philips.lighting.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingConstants; import javax.swing.border.Border; import com.philips.lighting.ImageProcessor; import com.philips.lighting.data.HueProperties; import com.philips.lighting.hue.sdk.PHHueSDK; import com.philips.lighting.hue.sdk.utilities.PHUtilities; import com.philips.lighting.model.PHBridge; import com.philips.lighting.model.PHLight; import com.philips.lighting.model.PHLightState; /** * ScreenshotsFrame.java * */ public class ScreenshotsFrame extends JFrame { private static final long serialVersionUID = -3830092035262367974L; private PHHueSDK phHueSDK; private JList <String> lightIdentifiersList; private List<PHLight> allLights; static String defaultIndicator = "<html><body><span style='color:gray; font-size: 45px'>\u2022</span></body></html>"; static JComboBox<String> comboBox_area_1 = new JComboBox<String>(); static JComboBox<String> comboBox_area_2 = new JComboBox<String>(); static JComboBox<String> comboBox_area_3 = new JComboBox<String>(); static JLabel color1 = new JLabel(defaultIndicator, JLabel.CENTER); static JLabel color2 = new JLabel(defaultIndicator, JLabel.CENTER); static JLabel color3 = new JLabel(defaultIndicator, JLabel.CENTER); static JLabel log = new JLabel("", JLabel.CENTER); public static boolean isProcessing = false; static JButton changeColourButton = new JButton("Start"); public ScreenshotsFrame() { super("Lights"); // The the HueSDK singleton. phHueSDK = PHHueSDK.getInstance(); Container content = getContentPane(); // Get the selected bridge. PHBridge bridge = phHueSDK.getSelectedBridge(); // To get lights use the Resource Cache. allLights = bridge.getResourceCache().getAllLights(); JScrollPane listPane = new JScrollPane(lightIdentifiersList); listPane.setPreferredSize(new Dimension(300,100)); JPanel listPanel = new JPanel(); listPanel.setBackground(Color.white); listPanel.add(listPane); content.add(listPanel); // First Area JLabel labelArea1 = new JLabel("Left area light"); labelArea1.setHorizontalAlignment(SwingConstants.CENTER); labelArea1.setBounds(20, 40, 230, 16); content.add(labelArea1); comboBox_area_1.setBounds(20, 60, 230, 27); comboBox_area_1.addItem(""); content.add(comboBox_area_1); color1.setBounds(20, 85, 230, 32); content.add(color1); // Second Area JLabel labelArea2 = new JLabel("Center area light"); labelArea2.setHorizontalAlignment(SwingConstants.CENTER); labelArea2.setBounds(255, 40, 230, 16); content.add(labelArea2); comboBox_area_2.setBounds(255, 60, 230, 27); comboBox_area_2.addItem(""); content.add(comboBox_area_2); color2.setBounds(255, 85, 230, 32); content.add(color2); // Third Area JLabel labelArea3 = new JLabel("Right area light"); labelArea3.setHorizontalAlignment(SwingConstants.CENTER); labelArea3.setBounds(490, 40, 230, 16); content.add(labelArea3); comboBox_area_3.setBounds(490, 60, 230, 27); comboBox_area_3.addItem(""); content.add(comboBox_area_3); color3.setBounds(490, 85, 230, 32); content.add(color3); log.setBounds(490, 60, 230, 32); content.add(log); // Fill lists with lights for (PHLight light : allLights) { comboBox_area_1.addItem(light.getIdentifier() + " " + light.getName() ); comboBox_area_2.addItem(light.getIdentifier() + " " + light.getName() ); comboBox_area_3.addItem(light.getIdentifier() + " " + light.getName() ); } // Start / Stop button changeColourButton.addActionListener(new ScreenshotProcessor()); Border buttonPanelBorder = BorderFactory.createEmptyBorder(); JPanel buttonPanel = new JPanel(); buttonPanel.setBackground(Color.white); buttonPanel.setBorder(buttonPanelBorder); buttonPanel.add(changeColourButton); content.add(buttonPanel, BorderLayout.SOUTH); setPreferredSize(new Dimension(740,400)); pack(); setVisible(true); } private static BufferedImage resizeImage(BufferedImage originalImage, int type) { int width = 640; int imageWidth = originalImage.getWidth(); int scale = 1; if (imageWidth > width) { scale = Math.round(imageWidth / width); } int height = Math.round(originalImage.getHeight() / scale); BufferedImage resizedImage = new BufferedImage(width, height, type); Graphics2D g = resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, width, height, null); g.dispose(); return resizedImage; } private class ScreenshotProcessor implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // Create temp folder if not exits Path path = Paths.get(HueProperties.getFolderPath() + "/temp/"); if (Files.notExists(path)) { (new File(HueProperties.getFolderPath() + "/temp/")).mkdirs(); } comboBox_area_1.setEnabled(false); comboBox_area_2.setEnabled(false); comboBox_area_3.setEnabled(false); // Start processing images isProcessing = !isProcessing; if (isProcessing) { step(); changeColourButton.setText("Stop"); } else { changeColourButton.setText("Start"); comboBox_area_1.setEnabled(true); comboBox_area_2.setEnabled(true); comboBox_area_3.setEnabled(true); } } } public void step() { ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { // Run event long startTime = System.currentTimeMillis(); List<Object> colorAndSaturationArray = new ArrayList<Object>(); // Read directory String folderPath = HueProperties.getFolderPath(); final File folder = new File(folderPath); final File tempFolder = new File(folderPath + "/temp/"); String tempPath = null; BufferedImage image = null; File[] files = folder.listFiles(); Arrays.sort(files, new Comparator<File>() { public int compare(File a, File b) { return (int) (b.lastModified() - a.lastModified()); } }); int fileCount = 0; for (final File fileEntry : files) { if (!fileEntry.isDirectory() && !fileEntry.isHidden()) { fileCount = fileCount + 1; } } if (fileCount > 0) { int i = 0; for (final File fileEntry : files) { if (!fileEntry.isDirectory() && !fileEntry.isHidden()) { if (i == 0) { tempPath = folderPath + "/temp/" + fileEntry.getName(); if (fileEntry.renameTo(new File(tempPath))) { // move file java.net.URL url = null; try { url = new File(tempPath).toURI().toURL(); } catch (MalformedURLException e1) { e1.printStackTrace(); } try { // Resize image to speed up getting most common color File f = new File(tempPath); if (f.exists() && f.canRead()) { BufferedImage originalImage = ImageIO.read(f); System.out.println("Type for " + tempPath + ":"); if (originalImage != null){ System.out.println(originalImage); int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType(); BufferedImage resizeImageJpg = resizeImage(originalImage, type); ImageIO.write(resizeImageJpg, "jpg", f); image = ImageIO.read(url); } } } catch (IOException e1) { e1.printStackTrace(); } } } i++; } } // Delete all files in folder for (final File fileEntry : folder.listFiles()) { if (!fileEntry.isDirectory() && fileEntry.exists()) { fileEntry.delete(); // Delete file } } } if (image != null) { int i = 0; // Get Image color in three vertical parts for (i = 1; i <= 3; i++) { // Get Dominant color from image part Object[] colorAndSaturation = ImageProcessor.getDominantColor(image, true, i); colorAndSaturationArray.add(colorAndSaturation); } // TODO improve this code, is not very efficient for (int j = 0; j < 3; j++) { // 3 is the number of lights int selectedIndex = 0; if ((j + 1) == 1) { selectedIndex = comboBox_area_1.getSelectedIndex() - 1; } if ((j + 1) == 2) { selectedIndex = comboBox_area_2.getSelectedIndex() - 1; } if ((j + 1) == 3) { selectedIndex = comboBox_area_3.getSelectedIndex() - 1; } if (selectedIndex >= 0) { Object[] colorAndSaturation = (Object[]) colorAndSaturationArray.get(j); System.out.println("index size:"); System.out.println(colorAndSaturation.length); Color rgbcolor = (Color) colorAndSaturation[0]; if (rgbcolor.getRed() > 0 && rgbcolor.getGreen() > 0 && rgbcolor.getBlue() > 0) { Object saturation = colorAndSaturation[1]; String lightIdentifer = allLights.get(selectedIndex).getIdentifier(); // Update state of LIght PHLightState lightState = new PHLightState(); float xy[] = PHUtilities.calculateXYFromRGB(rgbcolor.getRed(), rgbcolor.getGreen(), rgbcolor.getBlue(), allLights.get(selectedIndex).getModelNumber()); lightState.setX(xy[0]); lightState.setY(xy[1]); lightState.setOn(true); lightState.setBrightness((Integer) saturation); phHueSDK.getSelectedBridge().updateLightState(lightIdentifer, lightState, null); // null is passed here as we are not interested in the response from the Bridge. // Update color indicators if(j+1 == 1) { color1.setText("<html><body><span style='color:rgb("+rgbcolor.getRed()+","+rgbcolor.getGreen()+","+rgbcolor.getBlue()+",); font-size: 45px'>\u2022</span></body></html>"); } else if(j+1 == 2) { color2.setText("<html><body><span style='color:rgb("+rgbcolor.getRed()+","+rgbcolor.getGreen()+","+rgbcolor.getBlue()+",); font-size: 45px'>\u2022</span></body></html>"); } else if(j+1 == 3) { color3.setText("<html><body><span style='color:rgb("+rgbcolor.getRed()+","+rgbcolor.getGreen()+","+rgbcolor.getBlue()+",); font-size: 45px'>\u2022</span></body></html>"); } } } } // Delete all files in temp folder for (final File fileEntry : tempFolder.listFiles()) { if (!fileEntry.isDirectory() && fileEntry.exists()) { fileEntry.delete(); // Delete file } } long endTime = System.currentTimeMillis(); long duration = endTime - startTime; String text = "Image processd in " + duration + "ms"; log.setText(text); System.out.println(text); if (isProcessing) { step(); } } else { if (isProcessing) { step(); } } } }; // Timeout javax.swing.Timer t = new javax.swing.Timer(100, taskPerformer); t.setRepeats(false); t.start(); } }