Class MotionDetection

  • All Implemented Interfaces:
    java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable, java.lang.Runnable, javax.accessibility.Accessible, javax.swing.RootPaneContainer, javax.swing.WindowConstants

    public class MotionDetection
    extends javax.swing.JFrame
    implements java.lang.Runnable
    MotionDetection is a program for the RaspberryPi computer and camera to take a series of photos and detect motion in the images. It does this by dividing the image up into a series of boxes of about 1% of the image dimensions. These boxes are then compared for an average brightness and if the brightness difference between the same area on the two images exceeds the threshold in a minimum number of boxes the image is marked as having motion. The marked images may be saved to storage or emailed. Either the last image taken or a composite image made up of the last two images and a set of blue boxes marking the areas that exceeded the brightness threshold may be displayed. The dimensions of the captured images and the size of the image displayed on the program may be selected from program menus. All program parameters are saved to a file stored in the user's home directory.
    Program Revisions
    VersionDateModification
    0.10.0beta08 Jan 2017 incept
    0.12.0beta09 Jan 2017fix bug in directory file chooser
    0.13.0beta10 Jan 2017rewrite directory selection code and make minor changes to comments and directions
    0.20.012 Jan 2017move the image processing code off to a separate thread
    0.21.013 Jan 2017correct bad index in image processing code and get rid of one thread
    0.21.115 Jan 2017clean up javadocs and comments
    0.22.008 Feb 2017set the raspistill timeout to 1000ms to get the exposure correct on the images
    0.23.009 Feb 2017make sure to close the InputStream from the process running raspistill
    0.23.116 Feb 2017minor changes to the options passed to raspistill
    0.24.023 Mar 2017add alligator to main thread to destroy process if it hangs
    0.25.005 Apr 2017change the command line options to raspistill to get the image slightly faster
    0.30.005 May 2017change the way we are using raspistill to run it in timelapse mode and collect the image files to a ramdisk then read those files off the disk and put them in the processing queue - this allows us to collect images from raspistill every 500ms even with large image sizes
    0.31.006 May 2017clean up and simplify the ProcessBuilder code
    0.32.007 May 2017more code cleanup
    0.33.008 May 2017simplify ProcessManager code, organize code in CaptureSizeAction and stop(), and increase the image processing threads to four
    0.40.009 May 2017get rid of the transfer queue and associated code and clean up the processImage method
    0.41.010 May 2017clean up the code that keeps track of the display aspect ratio and add some 3x2 aspect ratio capture sizes
    0.42.012 May 2017store properties whenever data changes rather than just when the program stops
    0.50.014 May 2017add option to email captured photos
    0.51.015 May 2017add code to default the SSL email protocols
    0.51.115 May 2017clean up javadocs and code comments
    0.52.015 May 2017fixed a bug where the image about to be saved or emailed was overwritten by the composite image and clean up the status messages to the console
    0.60.018 May 2017change storeProperties method to run in new thread and do a lot of cleanup in processImage
    0.60.119 May 2017remove some redundant variables
    0.70.009 Jun 2017rewrite of the image scan code provided by Federico Pedemonte
    0.71.010 Jun 2017make the dot colors static variables and clean up the ramdisk file deletion code
    0.72.019 Feb 2018rewrite sendImage() to use a multipart message and replace several for loops with streams
    0.73.007 Apr 2018make some minor speed improvements in the processImage method
    0.74.008 Apr 2018improve timing code for testing
    0.75.017 Apr 2018add option to time stamp the images
    0.76.018 Apr 2018queue images for emailing rather than running multiple emailling threads simultaneously and add the milliseconds to image file names to prevent images being overwritten when more than one was taken in a given second
    0.77.019 Apr 2018modify time stamp code to draw in white or black depending on the brightness of the image
    0.77.119 Apr 2018update directions for the time stamp option
    0.78.019 Apr 2018change the time stamp code to adjust the font for the width of the image instead of the height
    0.78.120 Apr 2018rearrange the capture image sizes by aspect ratio and make minor comment and variable changes
    0.78.221 Apr 2018update program description in the javadocs and in the directions
    0.78.321 Apr 2018make a small optimization in the processImage method when testing for points
    0.78.421 Apr 2018minor changes to the stop method
    0.80.023 Apr 2018raspistill now writes to one file on the ramdisk, the processImage method has been changed to read the one file and then delete it, this simplifies the image handling and reduces the storage requirements on the ramdisk, in the createComposite method use the old image as the drawing surface instead of creating a new BufferedImage
    0.81.024 Apr 2018fix a bug I introduced into the createComposite method with version 0.80
    0.82.018 Oct 2018add --thumb none option to raspistill to reduce file size
    0.83.009 Dec 2018move the image time stamp to earlier in the processImage method so that saved and emailed files would be stamped correctly
    0.84.010 Dec 2018make changes to compile scripts, manifest file and the emailImage method to prepare for JDK11
    0.85.003 Mar 2019run through spotbugs and correct bug in RGB bit shift operations
    0.85.126 Mar 2019minor housekeeping
    0.86.014 Jul 2019turn off raspistill white balance to hopefully fix a problem that showed up in Buster
    0.87.021 Jul 2019remove the changes from 0.86.0, not required
    0.87.124 Jul 2019minor doc change
    Version:
    0.87.1 - 24 July 2019
    Author:
    Knute Johnson
    See Also:
    Serialized Form
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private class  MotionDetection.Auth
      An authenticator class used to obtain user name a password for sending email.
      private static class  MotionDetection.BufferedImageSource
      A DataSource to prepare a BufferedImage for emailing.
      private class  MotionDetection.CaptureSizeAction
      Action for the Capture Image Size JRadioMenuItems to set the capture size and adjust the display aspect ratio appropriately for the image.
      private class  MotionDetection.DisplaySizeAction
      Called when one of the Display Width radio buttons is clicked.
      private class  MotionDetection.EmailSettings
      A JPanel containing the GUI components to input email settings.
      private class  MotionDetection.ImageJPanel
      A specilized JPanel used to display the latest captured image and draw a dot in the upper right corner to signal a capture or an overload
      private static class  MotionDetection.Keys
      Timing data map keys, used for testing
      private static class  MotionDetection.ProcessManager
      ProcessManager is a class that combines the features of ProcessBuilder and Process and adds methods to handle the input and error streams.
      • Nested classes/interfaces inherited from class javax.swing.JFrame

        javax.swing.JFrame.AccessibleJFrame
      • Nested classes/interfaces inherited from class java.awt.Frame

        java.awt.Frame.AccessibleAWTFrame
      • Nested classes/interfaces inherited from class java.awt.Window

        java.awt.Window.AccessibleAWTWindow, java.awt.Window.Type
      • Nested classes/interfaces inherited from class java.awt.Container

        java.awt.Container.AccessibleAWTContainer
      • Nested classes/interfaces inherited from class java.awt.Component

        java.awt.Component.AccessibleAWTComponent, java.awt.Component.BaselineResizeBehavior, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static java.awt.AlphaComposite ALPHA_COMP
      Alpha composite used to create composite image for the display
      private double aspectRatio
      Display aspect ratio
      private int[][] brightNew
      Current image box values
      private int[][] brightOld
      Previous image box values
      private java.lang.Thread cameraThread
      Main program thread
      private static java.lang.String[] CAPTURE_SIZE_LABELS
      Capture size labels
      private int captureHeight
      Capture image height
      private int captureWidth
      Capture image width
      static java.lang.String DATE
      Program date
      private static java.lang.String DATE_PATTERN
      Date pattern for saved image files
      private java.io.File directory
      Directory where captured images are written
      private static java.lang.String[] DISPLAY_SIZE_LABELS
      Display size labels
      private int displayHeight
      Display image height
      private int displayWidth
      Display image width
      private boolean emailImage
      Flag if images are to be emailed
      private java.lang.Thread emailThread
      Email thread
      private javax.swing.JFileChooser fileChooser
      File chooser for saved images directory
      private java.awt.RenderingHints hints
      RenderingHints for all image drawing
      private static java.io.File IMAGE_FILE
      Image file
      private static java.time.format.DateTimeFormatter IMAGE_FILE_FORMATTER
      Date format for saved image files
      private java.awt.image.BufferedImage imageNew
      Current image
      private java.awt.image.BufferedImage imageOld
      Previous image
      private MotionDetection.ImageJPanel imagePanel
      Display panel for images
      private java.util.concurrent.BlockingQueue<java.awt.image.BufferedImage> imageQueue
      Queue for images to be emailed
      private static java.lang.String INI_FILE_NAME
      INI file name
      private double maxBoxes
      Maximum boxes value
      private double minBoxes
      Minimum boxes value
      private static int PROCESSORS
      Number of processors
      private java.lang.Thread processorThread
      Image processor thread
      private java.util.Properties properties
      Properties to store values set from menus
      private static int ROT
      Number of bits to rotate password string
      private boolean runFlag
      Main thread run flag
      private boolean saveFile
      Flag if images are to be saved
      private static long serialVersionUID
      Serial version UID
      private boolean showComposite
      Flag if composite images are to be displayed
      private double threshold
      Threshold value
      private static java.time.format.DateTimeFormatter TIME_STAMP_FORMATTER
      Date format for image time stamps
      private static java.lang.String TIME_STAMP_PATTERN
      Date patter for image time stamps
      private static boolean timesFlag
      Flag to print processing times on console
      private static java.awt.Font timeStampFont
      Default time stamp font
      private boolean timeStampImage
      Flag if images are to be time stamped
      private java.util.Map<MotionDetection.Keys,​java.util.List<java.lang.Long>> timingMap
      Timing data map, used for testing
      private static java.awt.Color TRANSLUCENT_GREEN
      Translucent green color for dot
      private static java.awt.Color TRANSLUCENT_RED
      Translucent red color for dot
      private static java.awt.Color TRANSPARENT_BLACK
      Transparent black color for dot
      private static java.io.File TXFER_DIR
      Transfer directory
      static java.lang.String VERSION
      Program version
      • Fields inherited from class javax.swing.JFrame

        accessibleContext, rootPane, rootPaneCheckingEnabled
      • Fields inherited from class java.awt.Frame

        CROSSHAIR_CURSOR, DEFAULT_CURSOR, E_RESIZE_CURSOR, HAND_CURSOR, ICONIFIED, MAXIMIZED_BOTH, MAXIMIZED_HORIZ, MAXIMIZED_VERT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NORMAL, NW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, W_RESIZE_CURSOR, WAIT_CURSOR
      • Fields inherited from class java.awt.Component

        BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
      • Fields inherited from interface java.awt.image.ImageObserver

        ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
      • Fields inherited from interface javax.swing.WindowConstants

        DISPOSE_ON_CLOSE, DO_NOTHING_ON_CLOSE, EXIT_ON_CLOSE, HIDE_ON_CLOSE
    • Constructor Summary

      Constructors 
      Constructor Description
      MotionDetection()
      Creates a new MotionDetection program
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private java.awt.image.BufferedImage createCompositeImage​(java.awt.image.BufferedImage img1, java.awt.image.BufferedImage img2, java.util.List<java.awt.Point> points, int boxWidth, int boxHeight)
      Draws img2 and blue boxes specified by the List points onto img1
      private void emailImage()
      Sends the captured image(s) via email using the entered settings.
      static void main​(java.lang.String... args)
      Main program entry point
      private void processImage()
      Read the latest image file from the ramdisk and process it for motion detection.
      private java.lang.String rotateLeft​(java.lang.String str, int shift)
      A method to obfuscate String data by rotating the bits in each character of the String to the left.
      private java.lang.String rotateRight​(java.lang.String str, int shift)
      A method to obfuscate String data by rotating the bits in each character of the String to the right.
      private byte rotl7​(byte b, int shift)
      Method to rotate the seven lower order bits of a byte by the specified number of bits to the left.
      private byte rotr7​(byte b, int shift)
      Method to rotate the seven lower order bits of a byte by the specified number of bits to the right.
      void run()
      The camera thread controls the process that runs the raspistill program.
      private void saveImage​(java.awt.image.BufferedImage image, java.io.File directory)
      Writes an image to the specified directory with the file name created from the local date and time in a background thread.
      private void start()
      Starts the camera thread and the image processing thread
      private void stop()
      Kill the raspistill program, stop the camera thread, the image processing thread, delete any remaining files on the ramdisk, unmount the ramdisk and remove it.
      private void storeProperties()
      Store the program properties to the INI file
      • Methods inherited from class javax.swing.JFrame

        addImpl, createRootPane, frameInit, getAccessibleContext, getContentPane, getDefaultCloseOperation, getGlassPane, getGraphics, getJMenuBar, getLayeredPane, getRootPane, getTransferHandler, isDefaultLookAndFeelDecorated, isRootPaneCheckingEnabled, paramString, processWindowEvent, remove, repaint, setContentPane, setDefaultCloseOperation, setDefaultLookAndFeelDecorated, setGlassPane, setIconImage, setJMenuBar, setLayeredPane, setLayout, setRootPane, setRootPaneCheckingEnabled, setTransferHandler, update
      • Methods inherited from class java.awt.Frame

        addNotify, getCursorType, getExtendedState, getFrames, getIconImage, getMaximizedBounds, getMenuBar, getState, getTitle, isResizable, isUndecorated, remove, removeNotify, setBackground, setCursor, setExtendedState, setMaximizedBounds, setMenuBar, setOpacity, setResizable, setShape, setState, setTitle, setUndecorated
      • Methods inherited from class java.awt.Window

        addPropertyChangeListener, addPropertyChangeListener, addWindowFocusListener, addWindowListener, addWindowStateListener, applyResourceBundle, applyResourceBundle, createBufferStrategy, createBufferStrategy, dispose, getBackground, getBufferStrategy, getFocusableWindowState, getFocusCycleRootAncestor, getFocusOwner, getFocusTraversalKeys, getIconImages, getInputContext, getListeners, getLocale, getModalExclusionType, getMostRecentFocusOwner, getOpacity, getOwnedWindows, getOwner, getOwnerlessWindows, getShape, getToolkit, getType, getWarningString, getWindowFocusListeners, getWindowListeners, getWindows, getWindowStateListeners, hide, isActive, isAlwaysOnTop, isAlwaysOnTopSupported, isAutoRequestFocus, isFocusableWindow, isFocusCycleRoot, isFocused, isLocationByPlatform, isOpaque, isShowing, isValidateRoot, pack, paint, postEvent, processEvent, processWindowFocusEvent, processWindowStateEvent, removeWindowFocusListener, removeWindowListener, removeWindowStateListener, reshape, setAlwaysOnTop, setAutoRequestFocus, setBounds, setBounds, setCursor, setFocusableWindowState, setFocusCycleRoot, setIconImages, setLocation, setLocation, setLocationByPlatform, setLocationRelativeTo, setMinimumSize, setModalExclusionType, setSize, setSize, setType, setVisible, show, toBack, toFront
      • Methods inherited from class java.awt.Container

        add, add, add, add, add, addContainerListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getAlignmentX, getAlignmentY, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalPolicy, getInsets, getLayout, getMaximumSize, getMinimumSize, getMousePosition, getPreferredSize, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, print, printComponents, processContainerEvent, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusTraversalKeys, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setFont, transferFocusDownCycle, validate, validateTree
      • Methods inherited from class java.awt.Component

        action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, contains, createImage, createImage, createVolatileImage, createVolatileImage, disable, disableEvents, dispatchEvent, enable, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBaseline, getBaselineResizeBehavior, getBounds, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground, getGraphicsConfiguration, getHeight, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocation, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getSize, getTreeLock, getWidth, getX, getY, gotFocus, handleEvent, hasFocus, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isDoubleBuffered, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isPreferredSizeSet, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, prepareImage, prepareImage, printAll, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processKeyEvent, processMouseEvent, processMouseMotionEvent, processMouseWheelEvent, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, requestFocus, requestFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, requestFocusInWindow, resize, resize, revalidate, setComponentOrientation, setDropTarget, setEnabled, setFocusable, setFocusTraversalKeysEnabled, setForeground, setIgnoreRepaint, setLocale, setMaximumSize, setMixingCutoutShape, setName, setPreferredSize, show, size, toString, transferFocus, transferFocusBackward, transferFocusUpCycle
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.awt.MenuContainer

        getFont, postEvent
    • Field Detail

      • serialVersionUID

        private static final long serialVersionUID
        Serial version UID
        See Also:
        Constant Field Values
      • CAPTURE_SIZE_LABELS

        private static final java.lang.String[] CAPTURE_SIZE_LABELS
        Capture size labels
      • DISPLAY_SIZE_LABELS

        private static final java.lang.String[] DISPLAY_SIZE_LABELS
        Display size labels
      • INI_FILE_NAME

        private static final java.lang.String INI_FILE_NAME
        INI file name
        See Also:
        Constant Field Values
      • TXFER_DIR

        private static final java.io.File TXFER_DIR
        Transfer directory
      • IMAGE_FILE

        private static final java.io.File IMAGE_FILE
        Image file
      • ROT

        private static final int ROT
        Number of bits to rotate password string
        See Also:
        Constant Field Values
      • PROCESSORS

        private static final int PROCESSORS
        Number of processors
      • TRANSPARENT_BLACK

        private static final java.awt.Color TRANSPARENT_BLACK
        Transparent black color for dot
      • TRANSLUCENT_RED

        private static final java.awt.Color TRANSLUCENT_RED
        Translucent red color for dot
      • TRANSLUCENT_GREEN

        private static final java.awt.Color TRANSLUCENT_GREEN
        Translucent green color for dot
      • timesFlag

        private static boolean timesFlag
        Flag to print processing times on console
      • DATE_PATTERN

        private static final java.lang.String DATE_PATTERN
        Date pattern for saved image files
        See Also:
        Constant Field Values
      • IMAGE_FILE_FORMATTER

        private static final java.time.format.DateTimeFormatter IMAGE_FILE_FORMATTER
        Date format for saved image files
      • TIME_STAMP_PATTERN

        private static final java.lang.String TIME_STAMP_PATTERN
        Date patter for image time stamps
        See Also:
        Constant Field Values
      • TIME_STAMP_FORMATTER

        private static final java.time.format.DateTimeFormatter TIME_STAMP_FORMATTER
        Date format for image time stamps
      • cameraThread

        private final java.lang.Thread cameraThread
        Main program thread
      • processorThread

        private final java.lang.Thread processorThread
        Image processor thread
      • emailThread

        private final java.lang.Thread emailThread
        Email thread
      • runFlag

        private volatile boolean runFlag
        Main thread run flag
      • captureWidth

        private volatile int captureWidth
        Capture image width
      • captureHeight

        private volatile int captureHeight
        Capture image height
      • aspectRatio

        private double aspectRatio
        Display aspect ratio
      • displayWidth

        private int displayWidth
        Display image width
      • displayHeight

        private int displayHeight
        Display image height
      • saveFile

        private volatile boolean saveFile
        Flag if images are to be saved
      • emailImage

        private volatile boolean emailImage
        Flag if images are to be emailed
      • timeStampImage

        private volatile boolean timeStampImage
        Flag if images are to be time stamped
      • timeStampFont

        private static final java.awt.Font timeStampFont
        Default time stamp font
      • ALPHA_COMP

        private static final java.awt.AlphaComposite ALPHA_COMP
        Alpha composite used to create composite image for the display
      • showComposite

        private volatile boolean showComposite
        Flag if composite images are to be displayed
      • fileChooser

        private final javax.swing.JFileChooser fileChooser
        File chooser for saved images directory
      • directory

        private volatile java.io.File directory
        Directory where captured images are written
      • hints

        private final java.awt.RenderingHints hints
        RenderingHints for all image drawing
      • threshold

        private volatile double threshold
        Threshold value
      • minBoxes

        private volatile double minBoxes
        Minimum boxes value
      • maxBoxes

        private volatile double maxBoxes
        Maximum boxes value
      • properties

        private final java.util.Properties properties
        Properties to store values set from menus
      • imageOld

        private java.awt.image.BufferedImage imageOld
        Previous image
      • imageNew

        private java.awt.image.BufferedImage imageNew
        Current image
      • brightOld

        private int[][] brightOld
        Previous image box values
      • brightNew

        private int[][] brightNew
        Current image box values
      • imageQueue

        private final java.util.concurrent.BlockingQueue<java.awt.image.BufferedImage> imageQueue
        Queue for images to be emailed
      • timingMap

        private final java.util.Map<MotionDetection.Keys,​java.util.List<java.lang.Long>> timingMap
        Timing data map, used for testing
    • Constructor Detail

      • MotionDetection

        public MotionDetection()
        Creates a new MotionDetection program
    • Method Detail

      • start

        private void start()
        Starts the camera thread and the image processing thread
      • run

        public void run()
        The camera thread controls the process that runs the raspistill program.
        Specified by:
        run in interface java.lang.Runnable
      • processImage

        private void processImage()
        Read the latest image file from the ramdisk and process it for motion detection. The processing is split into 4 threads to speed things up.
      • stop

        private void stop()
        Kill the raspistill program, stop the camera thread, the image processing thread, delete any remaining files on the ramdisk, unmount the ramdisk and remove it.
      • storeProperties

        private void storeProperties()
        Store the program properties to the INI file
      • saveImage

        private void saveImage​(java.awt.image.BufferedImage image,
                               java.io.File directory)
        Writes an image to the specified directory with the file name created from the local date and time in a background thread.
        Parameters:
        image - the image to save
        directory - the directory to save that image file in
      • emailImage

        private void emailImage()
        Sends the captured image(s) via email using the entered settings.
      • createCompositeImage

        private java.awt.image.BufferedImage createCompositeImage​(java.awt.image.BufferedImage img1,
                                                                  java.awt.image.BufferedImage img2,
                                                                  java.util.List<java.awt.Point> points,
                                                                  int boxWidth,
                                                                  int boxHeight)
        Draws img2 and blue boxes specified by the List points onto img1
        Parameters:
        img1 - the older image
        img2 - the new image
        points - list of upper left corner points
        boxWidth - width of the boxes in pixels
        boxHeight - height of the boxes in pixels
        Returns:
        the older image with the newer image and boxes drawn over it
      • rotateLeft

        private java.lang.String rotateLeft​(java.lang.String str,
                                            int shift)
        A method to obfuscate String data by rotating the bits in each character of the String to the left. Used to obfuscate the user's password.
        Parameters:
        str - the String to be obfuscated
        shift - the number of bits to rotate in the character
        Returns:
        the left rotated/obfuscated String
      • rotateRight

        private java.lang.String rotateRight​(java.lang.String str,
                                             int shift)
        A method to obfuscate String data by rotating the bits in each character of the String to the right. Used to obfuscate the user's password.
        Parameters:
        str - the String to be obfuscated
        shift - the number of bits to rotate in the character
        Returns:
        the right rotated/obfuscated String
      • rotl7

        private byte rotl7​(byte b,
                           int shift)
        Method to rotate the seven lower order bits of a byte by the specified number of bits to the left.
        Parameters:
        b - the byte to rotate
        shift - the number of bits to rotate
        Returns:
        the byte with the lower order bits rotated left
        Throws:
        java.lang.IllegalArgumentException - if the shift value is negative
      • rotr7

        private byte rotr7​(byte b,
                           int shift)
        Method to rotate the seven lower order bits of a byte by the specified number of bits to the right.
        Parameters:
        b - the byte to rotate
        shift - the number of bits to rotate
        Returns:
        the byte with the lower order bits rotated right
        Throws:
        java.lang.IllegalArgumentException - if the shift value is negative
      • main

        public static void main​(java.lang.String... args)
        Main program entry point
        Parameters:
        args - command line arguments, used for testing