|
Urbi SDK Remote for Java
2.7.5
|
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