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();
}
}