Urbi SDK Remote for Java  2.7.5
ImageSampler.java
00001 /*
00002  * Copyright (C) 2010-2011, Gostai S.A.S.
00003  *
00004  * This software is provided "as is" without warranty of any kind,
00005  * either expressed or implied, including but not limited to the
00006  * implied warranties of fitness for a particular purpose.
00007  *
00008  * See the LICENSE file for more information.
00009  */
00010 
00011 package urbi;
00012 
00013 import java.awt.*;
00014 import java.awt.color.*;
00015 import java.awt.event.*;
00016 import java.awt.geom.AffineTransform;
00017 import java.awt.image.*;
00018 import java.util.*;
00019 
00020 /**
00021  * The ImageSampler class displays a list of image processing operations.
00022  * A first frame contains the source image and a second frame contains
00023  * the user controls. If we want to process operations on the source image,
00024  * a third frame is created contained the last processed image.
00025  * <p>
00026  * <p>
00027  * @author Bastien Saltel
00028  */
00029 
00030 public class    ImageSampler extends Frame
00031 {
00032     /** The frame containing the source image. */
00033         private final Frame     imageFrame;
00034 
00035         /** The frame containing the processed image. */
00036         private Frame   imageFrame2 = null;
00037 
00038     /** The image component associated with the source image. */
00039         private final ImageComponent            imageComponent;
00040 
00041    /** The image component associated with the processed image. */
00042         private ImageComponent          imageComponent2 = null;
00043 
00044         /** The container of the image processing operators. */
00045         private Hashtable               ops;
00046 
00047     /** The last used image processing operator. */
00048         private BufferedImageOp op = null;
00049 
00050         /**
00051      * Constructor for ImageSampler. Displays the frame containing the user controls,
00052          * registers all the image processing operators and allocates the image component
00053          * associated with the source image.
00054      * <p>
00055          */
00056         public ImageSampler()
00057         {
00058                 super("Image Sampler");
00059                 imageFrame = new Frame("Image");
00060                 imageFrame.setLayout(new BorderLayout());
00061                 ImageUtilities.centerFrame(imageFrame);
00062                 createOps();
00063                 createUI();
00064                 setVisible(true);
00065                 imageFrame.setVisible(true);
00066                 imageComponent = new ImageComponent();
00067         }
00068 
00069         /**
00070          * Creates a table of image processing operators, calls createConvolutions,
00071          * createTransformations, createLookups and createRescales methods to create
00072          * a cornucopia of image operators.
00073          * <p>
00074          */
00075         private void    createOps()
00076         {
00077                 ops = new Hashtable();
00078                 createConvolutions();
00079                 createTransformations();
00080                 createLookups();
00081                 createRescales();
00082                 createColorOps();
00083         }
00084 
00085         /**
00086          * Creates convolutions operators.
00087          * <p>
00088          */
00089         private void    createConvolutions()
00090         {
00091                 float   ninth = 1.0f / 9.0f;
00092                 float[] blurKernel =
00093                         {
00094                                 ninth, ninth, ninth,
00095                                 ninth, ninth, ninth,
00096                                 ninth, ninth, ninth
00097                         };
00098                 ops.put("Blur", new ConvolveOp(new Kernel(3, 3, blurKernel),
00099                                                                            ConvolveOp.EDGE_NO_OP, null));
00100                 float[] sharp =
00101                         {
00102                                 0f, -1f, 0f,
00103                                 -1f, 5f, -1f,
00104                                 0f, -1f, 0f
00105                         };
00106                 ops.put("Sharpen", new ConvolveOp(new Kernel(3, 3, sharp)));
00107         }
00108 
00109         /**
00110          * Creates rotating and scaling operators.
00111          * <p>
00112          */
00113         private void    createTransformations()
00114         {
00115                 AffineTransform at;
00116                 at = AffineTransform.getRotateInstance(Math.PI / 6, 0, 285);
00117                 ops.put("Rotate nearest neighbor", new AffineTransformOp(at, null));
00118 
00119                 RenderingHints  rh = new RenderingHints(RenderingHints.KEY_INTERPOLATION,
00120                                                                                                 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
00121                 ops.put("Rotate bilinear", new AffineTransformOp(at, null));
00122 
00123                 at = AffineTransform.getScaleInstance(.5, .5);
00124                 ops.put("Scale .5, .5", new AffineTransformOp(at, null));
00125 
00126                 at = AffineTransform.getRotateInstance(Math.PI / 6);
00127                 ops.put("Rotate bilinear (origin)", new AffineTransformOp(at, rh));
00128         }
00129 
00130         /**
00131          * Creates brightening, posterizing, color inverting and removing operators.
00132          * <p>
00133          */
00134         private void    createLookups()
00135         {
00136                 short[] brighten = new short[256];
00137                 short[] betterBrighten = new short[256];
00138                 short[] posterize = new short[256];
00139                 short[] invert = new short[256];
00140                 short[] straight = new short[256];
00141                 short[] zero = new short[256];
00142 
00143                 for (int i = 0; i < 256; i++)
00144                         {
00145                                 brighten[i] = (short)(128 + i / 2);
00146                                 betterBrighten[i] = (short)(Math.sqrt((double)i / 255.0) * 255.0);
00147                                 posterize[i] = (short)(i - (i % 32));
00148                                 invert[i] = (short)(255 - i);
00149                                 straight[i] = (short)i;
00150                                 zero[i] = (short)0;
00151                         }
00152                 ops.put("Brighten", new LookupOp(new ShortLookupTable(0, brighten), null));
00153                 ops.put("Better Brighten", new LookupOp(new ShortLookupTable(0, betterBrighten), null));
00154                 ops.put("Posterize", new LookupOp(new ShortLookupTable(0, posterize), null));
00155                 ops.put("Invert", new LookupOp(new ShortLookupTable(0, invert), null));
00156 
00157                 short[][]               redOnly = {invert, straight, straight};
00158                 short[][]               greenOnly = {straight, invert, straight};
00159                 short[][]               blueOnly = {straight, straight, invert};
00160 
00161                 ops.put("Red invert", new LookupOp(new ShortLookupTable(0, redOnly), null));
00162                 ops.put("Green invert", new LookupOp(new ShortLookupTable(0, greenOnly), null));
00163                 ops.put("Blue invert", new LookupOp(new ShortLookupTable(0, blueOnly), null));
00164 
00165                 short[][]               redRemove = {zero, straight, straight};
00166                 short[][]               greenRemove = {straight, zero, straight};
00167                 short[][]               blueRemove = {straight, straight, zero};
00168 
00169                 ops.put("Red remove", new LookupOp(new ShortLookupTable(0, redRemove), null));
00170                 ops.put("Green remove", new LookupOp(new ShortLookupTable(0, greenRemove), null));
00171                 ops.put("Blue remove", new LookupOp(new ShortLookupTable(0, blueRemove), null));
00172         }
00173 
00174         /**
00175          * Creates rescaling operators.
00176          * <p>
00177          */
00178         private void    createRescales()
00179         {
00180                 ops.put("Rescale .5, 0", new RescaleOp(.5f, 0, null));
00181                 ops.put("Rescale .5, 64", new RescaleOp(.5f, 64, null));
00182                 ops.put("Rescale 1.2, 0", new RescaleOp(1.2f, 0, null));
00183                 ops.put("Rescale 1.5, 0", new RescaleOp(1.5f, 0, null));
00184         }
00185 
00186         /**
00187          * Creates color scaling operators.
00188          * <p>
00189          */
00190         private void    createColorOps()
00191         {
00192                 ops.put("Grayscale", new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null));
00193         }
00194 
00195         /**
00196          * Adds a new image to the frame.
00197          * <p>
00198          * @param buffer The buffer containing the binary data of the image.
00199          * @param width  The width of the image.
00200          * @param height The height of the image.
00201          */
00202         public synchronized void        addImage(byte[] buffer, int width, int height)
00203         {
00204                 imageComponent.setWidth(width);
00205                 imageComponent.setHeight(height);
00206                 imageComponent.setImage(buffer);
00207                 imageFrame.add(imageComponent, BorderLayout.CENTER);
00208                 ImageUtilities.sizeContainerToComponent(imageFrame, imageComponent);
00209                 if (imageFrame2 != null && imageComponent2 != null && imageComponent.getImage() != null)
00210                         {
00211                                 imageComponent2.setWidth(width);
00212                                 imageComponent2.setHeight(height);
00213                                 imageComponent2.setImage(op.filter(imageComponent.getImage(), null));
00214                                 imageFrame2.add(imageComponent2, BorderLayout.CENTER);
00215                                 ImageUtilities.sizeContainerToComponent(imageFrame2, imageComponent2);
00216                         }
00217                 imageFrame.setVisible(true);
00218         }
00219 
00220         public synchronized void        addImage(byte[] buffer, int width, int height, double x, double y)
00221         {
00222                 imageComponent.setWidth(width);
00223                 imageComponent.setHeight(height);
00224                 imageComponent.setImage(buffer, x, y);
00225                 imageFrame.add(imageComponent, BorderLayout.CENTER);
00226                 ImageUtilities.sizeContainerToComponent(imageFrame, imageComponent);
00227                 if (imageFrame2 != null && imageComponent2 != null && imageComponent.getImage() != null)
00228                         {
00229                                 imageComponent2.setWidth(width);
00230                                 imageComponent2.setHeight(height);
00231                                 imageComponent2.setImage(op.filter(imageComponent.getImage(), null));
00232                                 imageFrame2.add(imageComponent2, BorderLayout.CENTER);
00233                                 ImageUtilities.sizeContainerToComponent(imageFrame2, imageComponent2);
00234                         }
00235                 imageFrame.setVisible(true);
00236         }
00237 
00238         public synchronized void        addImage(BufferedImage buffer, int width, int height)
00239         {
00240                 imageComponent.setWidth(width);
00241                 imageComponent.setHeight(height);
00242                 imageComponent.setImage(buffer);
00243                 imageFrame.add(imageComponent, BorderLayout.CENTER);
00244                 ImageUtilities.sizeContainerToComponent(imageFrame, imageComponent);
00245                 if (imageFrame2 != null && imageComponent2 != null && imageComponent.getImage() != null)
00246                         {
00247                                 imageComponent2.setWidth(width);
00248                                 imageComponent2.setHeight(height);
00249                                 imageComponent2.setImage(op.filter(imageComponent.getImage(), null));
00250                                 imageFrame2.add(imageComponent2, BorderLayout.CENTER);
00251                                 ImageUtilities.sizeContainerToComponent(imageFrame2, imageComponent2);
00252                         }
00253                 imageFrame.setVisible(true);
00254         }
00255 
00256         public synchronized void        addImage(BufferedImage buffer, int width, int height, double x, double y)
00257         {
00258                 imageComponent.setWidth(width);
00259                 imageComponent.setHeight(height);
00260                 imageComponent.setImage(buffer, x, y);
00261                 imageFrame.add(imageComponent, BorderLayout.CENTER);
00262                 ImageUtilities.sizeContainerToComponent(imageFrame, imageComponent);
00263                 if (imageFrame2 != null && imageComponent2 != null && imageComponent.getImage() != null)
00264                         {
00265                                 imageComponent2.setWidth(width);
00266                                 imageComponent2.setHeight(height);
00267                                 imageComponent2.setImage(op.filter(imageComponent.getImage(), null));
00268                                 imageFrame2.add(imageComponent2, BorderLayout.CENTER);
00269                                 ImageUtilities.sizeContainerToComponent(imageFrame2, imageComponent2);
00270                         }
00271                 imageFrame.setVisible(true);
00272         }
00273 
00274         /**
00275          * Creates the user interface to process the image operations.
00276          * <p>
00277          */
00278         private void    createUI()
00279         {
00280                 setFont(new Font("Serif", Font.PLAIN, 12));
00281                 setLayout(new BorderLayout());
00282 
00283                 // Set our location to the left of the image frame.
00284                 setSize(200, 350);
00285                 Point   pt = imageFrame.getLocation();
00286                 setLocation(pt.x - getSize().width, pt.y);
00287 
00288                 final Label             statusLabel = new Label("");
00289 
00290                 // Make a sorted list of the operators.
00291                 Enumeration e = ops.keys();
00292                 Vector names = new Vector();
00293                 while (e.hasMoreElements())
00294                         names.addElement(e.nextElement());
00295                 Collections.sort(names);
00296 
00297                 final java.awt.List             list = new java.awt.List();
00298                 for (int i = 0; i < names.size(); i++)
00299                         list.add((String)names.elementAt(i));
00300                 add(list, BorderLayout.CENTER);
00301 
00302                 // When an item is selected, apply the corresponding transformation
00303                 list.addItemListener(new ItemListener()
00304                         {
00305                                 public void             itemStateChanged(ItemEvent ie)
00306                                 {
00307                                         if (imageComponent == null)
00308                                                 return ;
00309                                         if (ie.getStateChange() != ItemEvent.SELECTED)
00310                                                 return ;
00311                                         String  key = list.getSelectedItem();
00312 
00313                                         op = (BufferedImageOp)ops.get(key);
00314 
00315                                         if (imageFrame2 == null)
00316                                                 {
00317                                                         imageFrame2 = new Frame("Image Transformed");
00318                                                         imageFrame2.setLayout(new BorderLayout());
00319                                                         ImageUtilities.sizeContainerToComponent(imageFrame2, imageComponent);
00320                                                         Point   pt = imageFrame.getLocation();
00321                                                         imageFrame2.setLocation(pt.x, pt.y + imageFrame2.getSize().height);
00322                                                         imageFrame2.setVisible(true);
00323                                                         imageComponent2 = new ImageComponent();
00324                                                 }
00325 
00326                                         list.setEnabled(false);
00327                                         if (imageComponent.getImage() != null)
00328                                                 {
00329                                                         imageComponent2.setWidth(imageComponent.getWidth());
00330                                                         imageComponent2.setHeight(imageComponent.getHeight());
00331                                                         imageComponent2.setImage(op.filter(imageComponent.getImage(), null));
00332                                                 }
00333                                         imageComponent2.setSize(imageComponent2.getPreferredSize());
00334                                         imageFrame2.setSize(imageFrame2.getPreferredSize());
00335                                         list.setEnabled(true);
00336                                         statusLabel.setText("Performing " + key + "...done.");
00337                                 }
00338                         });
00339 
00340                 Panel bottom = new Panel(new GridLayout(2, 1));
00341                 bottom.add(statusLabel);
00342                 add(bottom, BorderLayout.SOUTH);
00343 
00344                 addWindowListener(new WindowAdapter()
00345                         {
00346                                 public void windowClosing(WindowEvent e)
00347                                 {
00348                                         imageFrame.dispose();
00349                                         if (imageFrame2 != null)
00350                                                 imageFrame2.dispose();
00351                                         dispose();
00352                                         System.exit(0);
00353                                 }
00354                         });
00355         }
00356 }
00357