package com.drawbridge.paper; import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.util.LinkedList; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JPanel; import org.opencv.core.Mat; import org.opencv.highgui.VideoCapture; import com.drawbridge.utils.AnalyticUtils; import com.drawbridge.utils.CVUtils; import com.drawbridge.utils.GraphicUtils; import com.drawbridge.utils.SegmentPanel; import com.drawbridge.utils.TitlePanel; import com.drawbridge.utils.Utils; public class PaperPanel extends SegmentPanel { private static final long serialVersionUID = 1L; private static PaperPanel mPaperPanel = null; private static VideoCapture camera = null; private final int padding = 25; private LinkedList<PaperPanelListener> mPaperPanelListeners = null; private BufferedImage mImage = null; private BufferedImage mPlaceholderImage = null; private ImageCanvas mImageCanvas = null; private WebcamPanel mWebcamPanel = null; private static final boolean mWebcamEnabled = false; /* Stops us getting bad data while releasing the camera */ private boolean cameraReleasing = false; private File mLastImageFile = null; public static PaperPanel getInstance() { if (mPaperPanel == null) { mPaperPanel = new PaperPanel(); return mPaperPanel; } return mPaperPanel; } private PaperPanel() { mPaperPanelListeners = new LinkedList<PaperPanelListener>(); this.setLayout(new BorderLayout()); TitlePanel mTitlePanel = new TitlePanel("Paper Panel"); add(mTitlePanel, BorderLayout.NORTH); mImageCanvas = new ImageCanvas(); add(mImageCanvas, BorderLayout.CENTER); // Load Placeholder Image mPlaceholderImage = GraphicUtils.loadImageFromResource("/Assets/placeholder.png"); // Add Change Image Button JButton changeImageButton = new JButton("Image File"); changeImageButton.setIcon(GraphicUtils.loadIconFromResource("/Assets/change-image.png")); changeImageButton.addMouseListener(new MouseAdapter(){ @Override public void mousePressed(MouseEvent me) { final JFileChooser fc = new JFileChooser(); int returnValue = fc.showOpenDialog(PaperPanel.this); switch(returnValue){ case JFileChooser.APPROVE_OPTION: mLastImageFile = fc.getSelectedFile(); loadImage(mLastImageFile.getAbsolutePath(), false); AnalyticUtils.recordLoadImageClick(); break; case JFileChooser.CANCEL_OPTION: break; case JFileChooser.ERROR_OPTION: break; } } }); mTitlePanel.addButton(changeImageButton); // Add Webcam Load Button if(mWebcamEnabled){ JButton webcamLoadButton = new JButton("Webcam Image"); webcamLoadButton.setIcon(GraphicUtils.loadIconFromResource("/Assets/webcam.png")); webcamLoadButton.addMouseListener(new MouseAdapter(){ @Override public void mousePressed(MouseEvent e) { new Thread(new Runnable(){ @Override public void run() { camera = new VideoCapture(0); camera.open(0); //Useless if(!camera.isOpened()){ System.out.println("Camera Error"); } else{ System.out.println("Camera OK?"); mWebcamPanel = new WebcamPanel(PaperPanel.this); PaperPanel.this.add(mWebcamPanel, BorderLayout.SOUTH); PaperPanel.this.validate(); try { Thread.sleep(1000); Mat frame = new Mat(); while(!cameraReleasing){ camera.read(frame); if(!frame.empty()){ Thread.sleep(200); Utils.out.println(getClass(), "Capturing webcam"); mImage = CVUtils.getBufferedImageFromMat(frame); mImageCanvas.repaint(); AnalyticUtils.recordWebcamClick(); } } cameraReleasing = false; } catch (InterruptedException e1) { e1.printStackTrace(); } } } }).start(); } }); mTitlePanel.addButton(webcamLoadButton); } addComponentListener(mComponentListener); } public ComponentListener mComponentListener = new ComponentAdapter(){ @Override public void componentResized(ComponentEvent e) { System.out.println("PaperPanel resized"); // if(mLastImageFile != null) // loadImage(mLastImageFile.getAbsolutePath(), false); } }; private void loadImage(final String name, final boolean resource){ java.awt.EventQueue.invokeLater(new Runnable(){ @Override public void run() { BufferedImage mBufferedImage = null; if(resource){ mBufferedImage = GraphicUtils.loadImageFromResource(name); } else{ mBufferedImage = GraphicUtils.loadImageFromFile(new File(name)); } // Create lower quality image. BufferedImage downsampledImage = new BufferedImage(mBufferedImage.getWidth(), mBufferedImage.getHeight(), BufferedImage.TYPE_USHORT_565_RGB); Graphics2D g2 = (Graphics2D) downsampledImage.getGraphics(); g2.setComposite(AlphaComposite.Src); g2.drawImage(downsampledImage, 0, 0, null); mImage = downsampledImage; Dimension newSize = GraphicUtils.getScaledDimFitInside(new Dimension(mBufferedImage.getWidth(), mBufferedImage.getHeight()), new Dimension(PaperPanel.this.getWidth() + padding, PaperPanel.this.getHeight() + padding)); mImage = getScaledImage(mBufferedImage, newSize.width, newSize.height); mImageCanvas.repaint(); /** Generate the layout **/ PaperPanel.this.validate(); fireOnUpdateEvent(); } }); } private BufferedImage getScaledImage(BufferedImage srcImg, int w, int h){ BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); Graphics2D g2 = resizedImg.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.drawImage(srcImg, 0, 0, w, h, null); g2.dispose(); return resizedImg; } public BufferedImage getImage(){ return mImage; } public void addOnUpdateListener(PaperPanelListener listener){ mPaperPanelListeners.add(listener); } public void fireOnUpdateEvent(){ if(mPaperPanelListeners == null || mPaperPanelListeners.size() == 0){ Utils.out.println(getClass(), "No listeners to fire updates to!"); } for(int i = 0; i < mPaperPanelListeners.size(); i++){ mPaperPanelListeners.get(i).onPaperPanelUpdate(this); Utils.out.println(getClass(), "Fired event update!"); } } public interface PaperPanelListener{ public void onPaperPanelUpdate(PaperPanel panel); } private class ImageCanvas extends JPanel{ private static final long serialVersionUID = 1L; public ImageCanvas(){ setBackground(Color.white); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); if(mImage != null){ Graphics2D g2 = (Graphics2D) g; int x = (getWidth() - mImage.getWidth()) / 2; int y = (getHeight() -mImage.getHeight()) / 2; g2.drawImage(mImage, x, y, mImage.getWidth(), mImage.getHeight(), null); } else{ Dimension d = new Dimension(mPlaceholderImage.getWidth(), mPlaceholderImage.getHeight()); Graphics2D g2 = (Graphics2D) g; int x = (getWidth() - d.width) / 2; int y = (getHeight() - d.height) / 2; g2.drawImage(mPlaceholderImage, x, y, d.width, d.height, null); } } } public void webcamCapture() { cameraReleasing = true; camera.release(); PaperPanel.this.remove(mWebcamPanel); PaperPanel.this.validate(); repaint(); fireOnUpdateEvent(); } public void webcamCancel() { if(camera != null) camera.release(); mImage = null; Utils.removeComponent(this, WebcamPanel.class); PaperPanel.this.validate(); repaint(); } }