Subversion Repositories svnkaklik

Rev

Blame | Last modification | View Log | Download

/*
    AVRcamVIEW: A PC application to test out the functionallity of the
     AVRcam real-time image processing engine.
    Copyright (C) 2004    Brent A. Taylor

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public
    License along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   For more information on the AVRcamVIEW, please contact:

   taylorba@comcast.net

   or go to www.jrobot.net for more details regarding the system.
*/

package avr.swing;

import java.awt.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.text.*;
import java.util.*;
import javax.swing.*;

import avr.device.event.*;
import avr.lang.*;

public class JTrackingPanel extends JPanel {

   private static final DateFormat DATE_FORMAT;

   static {
      DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh.mm.ss");
   }

   private ColorBlob[] blobs;
   private DataListener dataHandler;

   private Dimension preferredSize;

   private boolean recording;
   private boolean sendCameraData;

   private FileOutputStream outStream;
   private FileChannel outChannel;

   public JTrackingPanel() {
      super(null);

      recording = false;
      sendCameraData = false;

      setBackground(Color.BLACK);
      dataHandler = new TrackingHandler();

      preferredSize = null;
   }

   public void startRecording() throws FileNotFoundException {
      File recordFile = new File(DATE_FORMAT.format(new Date()) + ".trk");
      outStream = new FileOutputStream(recordFile);
      outChannel = outStream.getChannel();

      recording = true;

      AVRSystem.LOG.info("Started Recording");
   }

   public void stopRecording() throws IOException {

      recording = false;

      outStream.close();
      outChannel.close();

      AVRSystem.LOG.info("Stopped Recording");

   }

   public void startTracking() {
      AVRSystem.DEVICE.addDataListener(dataHandler);
   }

   public void stopTracking() {
      AVRSystem.DEVICE.removeDataListener(dataHandler);
   }

   public void startSendingCameraData() {
      sendCameraData = true;
   }

   public void stopSendingCameraData() {
      sendCameraData = false;
   }

   public Dimension getMinimumSize() {
      return getPreferredSize();
   }

   public Dimension getPreferredSize() {
      if(preferredSize == null) {
         Insets insets = this.getInsets();
         preferredSize = new Dimension(insets.left + AVRSystem.IMAGE_WIDTH + insets.right,
                                       insets.top + AVRSystem.IMAGE_HEIGHT + insets.bottom);
      }

      return preferredSize;
   }

   public Dimension getMaximumSize() {
      return getPreferredSize();
   }

   public void paintComponent(Graphics g) {

      super.paintComponent(g);

      Dimension size = getSize();

      Insets insets = getInsets();

      double xScale = size.width /
                      (double)(insets.left + 5 + AVRSystem.IMAGE_WIDTH + 5 +
                               insets.right);
      double yScale = size.height /
                      (double)(insets.top + 5 + AVRSystem.IMAGE_HEIGHT + 5 +
                               insets.bottom);
      double scale = Math.min(xScale, yScale);

      int imageWidth = (int)(AVRSystem.IMAGE_WIDTH * scale);
      int imageHeight = (int)(AVRSystem.IMAGE_HEIGHT * scale);

      // it is possible for the width or height to be 0 when
      // the window is resized.  If this occurs, don't try
      // to paint anything. just return
      if(imageWidth <= 0 || imageHeight <= 0) {
         return;
      }

      Image bufferedImage = createImage(imageWidth, imageHeight);

      Graphics2D bufferGraphics = (Graphics2D)bufferedImage.getGraphics();

      bufferGraphics.setColor(Color.WHITE);
      bufferGraphics.fillRect(0, 0, imageWidth, imageHeight);

      bufferGraphics.scale(scale, scale);

      for(int i = 0; (blobs != null) && (i < blobs.length); i++) {
         ColorBlob blob = blobs[i];
         if(blob != null) {
            bufferGraphics.setColor(AVRSystem.DEVICE.getMapColors()[blob.
                                    colorIndex]);
            bufferGraphics.fillRect(blob.center.x - 2, blob.center.y - 2, 4, 4);
            bufferGraphics.setColor(Color.BLACK);
            bufferGraphics.drawRect(blob.bounds.x, blob.bounds.y,
                                    blob.bounds.width, blob.bounds.height);
         }
      }

      g.drawImage(bufferedImage,
                  (size.width - imageWidth) / 2, (size.height - imageHeight) / 2,
                  imageWidth, imageHeight, this);


   }

   public void setTrackingData(ByteBuffer data) {
      blobs = new ColorBlob[data.get() & 0xFF];

      for(int i = 0; i < blobs.length; i++) {
         blobs[i] = new ColorBlob(data);
      }

      repaint();

      if(sendCameraData) {
         data.position(0);
         try {
            AVRSystem.DEVICE.sendCameraData(data);
         } catch(IOException ioe) {
            ioe.printStackTrace(System.err);
            AVRSystem.LOG.warning(ioe.getMessage());
         }
      }

   }

   private final class TrackingHandler extends DataAdapter {

      public void trackingData(ByteBuffer data) {
         setTrackingData(data);

         if(recording) {
            data.reset();
            try {
               outChannel.write(data);
            } catch(IOException ioe) {
               AVRSystem.LOG.warning("TRACKING: " + ioe.getMessage());
            }
         }

      }

   }

   private final static class ColorBlob {

      public final int colorIndex;
      public final Point center;
      public final Rectangle bounds;

      public ColorBlob(ByteBuffer data) {
         colorIndex = data.get();

         int x = data.get() & 0xFF;
         int y = data.get() & 0xFF;
         int width = (data.get() & 0xFF) - x;
         int height = (data.get() & 0xFF) - y;
         bounds = new Rectangle(x, y, width, height);

         center = new Point(x + (width / 2), y + (height / 2));
      }

      public String toString() {
         return "ColorBlob: " + colorIndex + " (" + center.x + ", " + center.y + ") " +
                " [" + bounds.x + ", " + bounds.y + ", " + bounds.width + ", " + bounds.height + "]";
      }


   }

}