edu.ku.brc.specify.plugins.imgproc.ImageProcessorPanel.java Source code

Java tutorial

Introduction

Here is the source code for edu.ku.brc.specify.plugins.imgproc.ImageProcessorPanel.java

Source

package edu.ku.brc.specify.plugins.imgproc;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

import edu.ku.brc.af.prefs.AppPreferences;
import edu.ku.brc.ui.IconManager;
import edu.ku.brc.ui.Trayable;
import edu.ku.brc.util.Pair;

/* Copyright (C) 2015, University of Kansas Center for Research
 * 
 * Specify Software Project, specify@ku.edu, Biodiversity Institute,
 * 1345 Jayhawk Boulevard, Lawrence, Kansas, 66045, USA
 * 
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

/**
 * @author rods
 *
 * @code_status Alpha
 *
 * Sep 10, 2011
 *
 */
public class ImageProcessorPanel extends JPanel {
    protected static final int PROC_ICON_SIZE = 120;
    protected static final int PROC_IMG_SIZE = 93;
    protected static BasicStroke lineStroke = new BasicStroke(1.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    protected static Font font = null;

    protected BarCodeDecoder barDecoder = new BarCodeDecoder();
    protected IconTray<Trayable> iconTray;

    protected Timer timer = null;
    protected String[] imgNames = { "png", "tif", "bmp", "gif", "jpg" };
    protected int imgIndex = 0;
    protected ImageIcon circle;
    protected ImageProcListener listener;
    protected Vector<TrayImageIcon> trayItems = new Vector<TrayImageIcon>();
    protected String srcDir = "/Users/rods/Pictures/Eye-Fi/Pics";

    protected int step = 0;
    protected int numPics = 3;
    protected int barcodePicInx = 0;

    protected String[] procImgNames = { "camera", "barcode", "metadata", "disk" };

    protected ArrayList<ProcessObject> procObjs = new ArrayList<ImageProcessorPanel.ProcessObject>();

    protected static RenderingHints hints;

    protected ArrayList<File> filesToProcess = new ArrayList<File>();

    static {
        hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    }

    /**
     * @param iconTray
     * @param listener
     */
    public ImageProcessorPanel(final IconTray<Trayable> iconTray, final ImageProcListener listener) {
        super(null);
        this.iconTray = iconTray;
        this.listener = listener;
    }

    /**
     * 
     */
    public void createUI() {
        Dimension s = new Dimension(350, 350);
        setSize(s);
        setPreferredSize(s);

        setBackground(Color.WHITE);
        for (String imgNm : procImgNames) {
            procObjs.add(new ProcessObject(imgNm));
        }

        circle = IconManager.getIcon("ip_circle");

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                doProcLayout();

                step = -1;

                doNextStep();
            }
        });
    }

    /**
     * 
     */
    protected void doProcLayout() {
        Dimension size = getSize();
        int margin = 20;

        Point p = new Point(margin, margin);
        for (int i = 0; i < 4; i++) {
            switch (i) {
            case 0:
                p.setLocation(margin, margin * 2);
                break;
            case 1:
                p.setLocation(size.width - PROC_ICON_SIZE - margin, margin * 2);
                break;
            case 2:
                p.setLocation(size.width - PROC_ICON_SIZE - margin, size.height - PROC_ICON_SIZE - margin);
                break;
            case 3:
                p.setLocation(margin, size.height - PROC_ICON_SIZE - margin);
                break;
            }
            add(procObjs.get(i));
            procObjs.get(i).setLocation(p);
            procObjs.get(i).setVisible(true);
        }
    }

    /* (non-Javadoc)
     * @see javax.swing.JComponent#paint(java.awt.Graphics)
     */
    @Override
    public void paint(Graphics g) {
        ((Graphics2D) g).addRenderingHints(hints);

        super.paint(g);

        if (font == null) {
            font = (new JLabel()).getFont();
            font = font.deriveFont(18.0f);
            font = font.deriveFont(Font.BOLD);
        }
        String title = "Specify Image Processor";
        g.setColor(new Color(32, 131, 155));
        g.setFont(font);
        int w = g.getFontMetrics().stringWidth(title);
        int y = g.getFontMetrics().getHeight() - 5;
        int x = (getSize().width - w) / 2;

        g.drawString(title, x, y);
    }

    /**
     * 
     */
    protected void startWatching() {
        timer = new Timer(1500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                acquireImages();
            }
        });
        timer.start();
    }

    /**
     * 
     */
    public void clearFiles() {
        File dir = new File(srcDir);

        if (dir != null && dir.exists()) {
            for (File f : dir.listFiles()) {
                String ext = FilenameUtils.getExtension(f.getName());
                if (!f.getName().startsWith(".") && ext != null
                        && (ext.equalsIgnoreCase("jpg") || ext.equalsIgnoreCase("png"))) {
                    f.delete();
                }
            }
        }
    }

    /**
     * 
     */
    protected void doNextStep() {
        if (step > -1) {
            procObjs.get(step).setOn(false);
        }

        step++;
        if (step >= procObjs.size()) {
            step = 0;
        }

        System.out.println("Step: " + step);

        procObjs.get(step).setOn(true);

        SwingWorker<Integer, Integer> worker = new SwingWorker<Integer, Integer>() {
            /* (non-Javadoc)
             * @see javax.swing.SwingWorker#doInBackground()
             */
            @Override
            protected Integer doInBackground() throws Exception {
                switch (step) {
                case 0:
                    acquireImages();
                    break;

                case 1:
                    processBarCode();
                    break;

                case 2:
                    processMetaData();
                    break;

                case 3:
                    processSaveToDisk();
                    break;

                }
                return null;
            }
        };
        worker.execute();
    }

    /**
     * 
     */
    protected void advance() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ImageProcessorPanel.this.doNextStep();
            }
        });

    }

    /**
     * 
     */
    protected void acquireImages() {
        if (timer != null) {
            timer.stop();
        }

        File dir = new File(srcDir);

        String nms[] = dir.list();
        int cnt = 0;
        if (nms.length > 0) {
            for (String s : nms) {
                if (!s.startsWith(".")) {
                    cnt++;
                }
            }
        }
        //System.out.println(dir.getAbsolutePath()+":  "+cnt);

        if (cnt == numPics) {
            filesToProcess.clear();
            trayItems.clear();
            iconTray.removeAllItems();

            File[] files = dir.listFiles();
            for (File f : files) {
                if (!f.getName().startsWith(".")) {
                    filesToProcess.add(f);
                    System.out.println("Add: " + f.getName());
                }
            }

            Comparator<File> fileComp = new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    return ((Long) o1.lastModified()).compareTo(o2.lastModified());
                }

            };
            Collections.sort(filesToProcess, fileComp);

            iconTray.removeAllItems();

            for (File f : filesToProcess) {
                System.out.println(f.getName());
                TrayImageIcon trayItem = new TrayImageIcon(f);
                iconTray.addItem(trayItem);
                trayItems.add(trayItem);
            }
            iconTray.repaint();

            advance();

        } else {
            startWatching();
        }
    }

    /**
     * 
     */
    public void readSetupPrefs() {
        AppPreferences locPrefs = AppPreferences.getLocalPrefs();
        numPics = locPrefs.getInt("IMGWRKFLW.PIC_CNT", 3);
        barcodePicInx = locPrefs.getInt("IMGWRKFLW.PIC_INX", 1);
        srcDir = locPrefs.get("IMGWRKFLW.PIC_DEST", "/Users/rods/Pictures/Eye-Fi/Pics");
    }

    /**
     * 
     */
    protected void processBarCode() {
        listener.statusMsg("Reading BarCode from image...");

        File file = filesToProcess.get(barcodePicInx);
        System.out.println("BarCode: " + file.getName());
        try {
            barDecoder.decode(file);
            String number = barDecoder.getNumber();
            if (StringUtils.isNotEmpty(number)) {
                listener.statusMsg("Barcode: " + number);

                ArrayList<File> imgFiles = new ArrayList<File>();

                System.out.println(trayItems.size());
                int cnt = 1;
                for (TrayImageIcon trayItem : trayItems) {
                    String ext = FilenameUtils.getExtension(trayItem.getFile().getName());
                    String nm = String.format("processedimages/%s_%d.%s", number, cnt, ext);
                    File newFile = new File(nm);

                    try {
                        FileUtils.copyFile(trayItem.getFile(), newFile);
                        imgFiles.add(newFile);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    trayItem.setFile(newFile);
                    cnt++;
                }

                try {
                    listener.complete(ImageProcListener.ActionType.eBarDecoding,
                            new Pair<String, ArrayList<File>>(number, imgFiles));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

            } else {
                listener.statusMsg("Error reading BarCode from image...");
            }
            iconTray.repaint();

        } catch (IOException e) {
            listener.statusMsg("Barcode Error!");
            e.printStackTrace();
        }

        advance();
    }

    /**
     * 
     */
    protected void processMetaData() {
        listener.statusMsg("Setting metadata...");

        //for (File f : filesToProcess) System.out.println("MetaData: "+f.getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        advance();
    }

    /**
     * 
     */
    protected void processSaveToDisk() {
        listener.statusMsg("Saving to disk...");
        //for (File f : filesToProcess) System.out.println("Save: "+f.getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        listener.statusMsg(" ");
        for (File f : filesToProcess)
            f.delete();
        filesToProcess.clear();
        iconTray.removeAllItems();
        iconTray.repaint();

        advance();
    }

    //-------------------------------------------------------------------------------
    class ProcessObject extends JPanel {
        protected Point imgPnt;
        protected ImageIcon img;
        protected boolean isOn;

        /**
         * @param nm
         * @param x
         * @param y
         */
        public ProcessObject(final String nm) {
            setSize(500, 500);
            setBorder(BorderFactory.createLineBorder(Color.BLACK));

            img = IconManager.getIcon(String.format("ip_%s", nm));

            setSize(PROC_ICON_SIZE, PROC_ICON_SIZE);
            setOpaque(false);
            setVisible(false);

            int offsetX = (PROC_ICON_SIZE - img.getIconWidth()) / 2;
            int offsetY = (PROC_ICON_SIZE - img.getIconHeight()) / 2;
            imgPnt = new Point(offsetX, offsetY);
        }

        /* (non-Javadoc)
         * @see javax.swing.JComponent#paint(java.awt.Graphics)
         */
        public void paint(final Graphics g) {
            Graphics2D g2d = (Graphics2D) g;

            //g2d.setColor(Color.BLACK);
            //g.drawRect(pnt.x, pnt.y, img.getIconWidth(), img.getIconHeight());

            g.drawImage(img.getImage(), imgPnt.x, imgPnt.y, null);

            if (isOn) {
                //int circleOffset = (circle.getIconWidth() - img.getIconWidth()) / 2;
                g.drawImage(circle.getImage(), 0, 0, null);
            }
            //int offset = img.getIconHeight() / 2;
            //g2d.setStroke(lineStroke);
            //g2d.setColor(Color.BLUE);
            //g2d.drawRect(0, 0, circle.getIconWidth()-1, circle.getIconHeight()-1);
            //GraphicsUtils.drawCircle(g, pnt.x+offset, pnt.y+offset, offset*2);
        }

        /**
         * @return the isOn
         */
        public boolean isOn() {
            return isOn;
        }

        /**
         * @param isOn the isOn to set
         */
        public void setOn(boolean isOn) {
            this.isOn = isOn;
            repaint();
        }

    }

}