/Users/lyon/j4p/src/j2d/ImageUtils.java
|
1 package j2d;
2
3 import com.sun.media.jai.codec.ImageCodec;
4 import com.sun.media.jai.codec.ImageEncoder;
5 import com.sun.media.jai.codec.TIFFEncodeParam;
6 import futils.Futil;
7 import futils.Out;
8 import futils.StreamSniffer;
9 import futils.WriterUtil;
10 import graphics.NumImage;
11 import gui.ClosableJFrame;
12 import gui.ImageBean;
13 import gui.ImageBeanInterface;
14 import gui.In;
15 import ip.ppm.WritePPM;
16 import ip.transforms.Kernels;
17 import j2d.color.PseudoColorFilter;
18 import j2d.filters.GaussianSmoothingProcessor;
19 import j2d.hpp.*;
20
21 import javax.swing.*;
22 import javax.imageio.ImageIO;
23 import java.awt.*;
24 import java.awt.geom.AffineTransform;
25 import java.awt.image.*;
26 import java.io.*;
27 import java.util.zip.GZIPOutputStream;
28
29 // ...
30
31 /**
32 * A toolkit of useful image processing methods.
33 * Declared as final, since all methods are static.
34 */
35 public final class ImageUtils {
36 /**
37 * make it so no one will instance this class.
38 */
39 private ImageUtils() {
40 }
41
42 public static void saveAsPPMgz(Image img, String fn) {
43 ShortImageBean sib = new ShortImageBean(img);
44 WritePPM wppm = new WritePPM(sib.getWidth(), sib.getHeight());
45 try {
46 GZIPOutputStream
47 os = new GZIPOutputStream(new FileOutputStream(fn));
48 wppm.writeHeader(os);
49 wppm.writeImage(os, sib.getR(), sib.getG(), sib.getB());
50 os.finish();
51 os.close();
52 } catch (Exception e) {
53 System.out.println("Save PPM Exception - 2!");
54 }
55 }
56
57 public static void saveAsPPMgz(Image img) {
58 String fn = WriterUtil.getSaveFileName("Save as PPM.gz");
59 if (fn == null) return;
60 saveAsPPMgz(img, fn);
61 }
62
63 public static void saveAsPPM(Image img, File f) {
64 ShortImageBean sib = new ShortImageBean(img);
65 WritePPM.doIt(sib.getR(),
66 sib.getG(),
67 sib.getB(),
68 f.toString());
69 }
70
71 public static void printImageWriterFormats() {
72 //print(ImageIO.getWriterFormatNames());
73 }
74
75 public static void printImageReaderFormats() {
76 String s[] = null; //ImageIO.getReaderFormatNames();
77 print(s);
78 }
79
80 public static void print(Object o[]) {
81 for (int i = 0; i < o.length; i++)
82 System.out.println(o[i]);
83 }
84
85 public static java.awt.Image getImage(java.awt.Component c) {
86 java.awt.Dimension d = c.getSize();
87 java.awt.Frame f = new java.awt.Frame();
88 f.addNotify();
89 f.setSize(d);
90 java.awt.Image i = f.createImage(d.width, d.height);
91
92 c.paint(i.getGraphics());
93 return i;
94 }
95
96 public static void testGetImage() {
97 ClosableJFrame cjf = new ClosableJFrame("test image");
98 Container c = cjf.getContentPane();
99 c.setLayout(new GridLayout(1, 0));
100 c.add(new imagePanel(getImage()));
101 c.add(new imagePanel(getImage()));
102 c.add(new imagePanel(getImage()));
103 c.add(new imagePanel(getImage()));
104 cjf.setSize(200, 200);
105 cjf.show();
106 }
107
108 public static java.awt.Image getImage() {
109 java.io.File f =
110 Futil.getReadFile("select an image");
111 if (f == null) return null;
112 InputStream is = null;
113 try {
114 is = new FileInputStream(f);
115 new StreamSniffer(is);
116 } catch (FileNotFoundException e) {
117 e.printStackTrace();
118 }
119 return getGifJpgPngImage(f);
120 }
121
122 public static Image getImage(String fn) {
123 File f = new File(fn);
124 if (f.exists())
125 return getGifJpgPngImage(f);
126 Out.messageDialog(f+" not found ImageUtils.getImage,using cameraman image");
127 return NumImage.getImage();
128 }
129
130 public static java.awt.Image getGifJpgPngImage(java.io.File f) {
131 java.awt.Image i =
132 java.awt.Toolkit.getDefaultToolkit().getImage(f.toString());
133 waitForImage(new gui.ClosableJFrame(), i);
134 return i;
135 }
136
137 public static void waitForImage(java.awt.Component c,
138 java.awt.Image image) {
139 if (c == null) waitForImage(image);
140 if (image == null) System.out.println("Image is Null!");
141 java.awt.MediaTracker tracker = new java.awt.MediaTracker(c);
142 try {
143 tracker.addImage(image, 0);
144 tracker.waitForID(0);
145 } catch (InterruptedException e) {
146 }
147 }
148
149 public static void waitForImage(java.awt.Image image) {
150 JPanel jp = new JPanel();
151 waitForImage(jp, image);
152 }
153
154 public static Image byte2Image(byte r[][]) {
155
156 int w = r.length;
157 int h = r[0].length;
158 int v = 0;
159 Toolkit tk = Toolkit.getDefaultToolkit();
160 int pels[] = new int[w * h];
161 for (int x = 0; x < w; x++)
162 for (int y = 0; y < h; y++) {
163 if (r[x][y] == 1)
164 v = 255;
165 else
166 v = 0;
167 pels[y + x * h] =
168 0xff000000
169 | (v << 16)
170 | (v << 8)
171 | v;
172 }
173 Image i = tk.createImage(new MemoryImageSource(w,
174 h,
175 ColorModel.getRGBdefault(),
176 pels, 0,
177 w));
178 return i;
179 }
180
181 public static Image short2Image(short r[][]) {
182
183 int w = r.length;
184 int h = r[0].length;
185 int v = 0;
186 Toolkit tk = Toolkit.getDefaultToolkit();
187 int pels[] = new int[w * h];
188 for (int x = 0; x < w; x++)
189 for (int y = 0; y < h; y++) {
190 v = r[x][y];
191 pels[y + x * h] =
192 0xff000000
193 | (v << 16)
194 | (v << 8)
195 | v;
196 }
197 Image i = tk.createImage(new MemoryImageSource(w,
198 h,
199 ColorModel.getRGBdefault(),
200 pels, 0,
201 w));
202 return i;
203 }
204
205
206 public static Image getImage(short r[][], short g[][], short b[][],
207 HppFilterInterface f) {
208
209 int w = r.length;
210 int h = r[0].length;
211
212 return getImage(getPels(r, g, b, f),
213 w, h);
214 }
215
216 public static Image getImage(short r[][], HppFilterInterface f) {
217 int w = r.length;
218 int h = r[0].length;
219 return getImage(getPels(r, f),
220 w, h);
221 }
222
223 private static int[] getPels(short[][] r, HppFilterInterface f) {
224 int w = r.length;
225 int h = r[0].length;
226
227 int pels[] = new int[w * h];
228 int v;
229 for (int x = 0; x < w; x++)
230 for (int y = 0; y < h; y++) {
231 v = r[x][y];
232 pels[y + x * h] =
233 packInt(f.getR(v),
234 f.getG(v),
235 f.getB(v));
236 }
237 return pels;
238 }
239
240 public static int[] short2Pels(short r[][], short g[][], short b[][]) {
241 int width = r.length;
242 int height = r[0].length;
243 int pels[] = new int[width * height];
244 for (int x = 0; x < width; x++)
245 for (int y = 0; y < height; y++)
246 pels[x + y * width]
247 = packInt(r[x][y],
248 g[x][y],
249 b[x][y]);
250 return pels;
251 }
252
253 /**
254 * Get the red part of a packed rgb int.
255 *
256 * @param rgb a pixel in argb format
257 * @return just the red part.
258 */
259 public static final short getRed(int rgb) {
260 return (short) ((rgb & 0xFF0000) >> 16);
261 }
262
263 /**
264 * Get the green part of a packed rgb int
265 *
266 * @param rgb a pixel in argb format
267 * @return just the green part.
268 */
269 public static final short getGreen(int rgb) {
270 return (short) ((rgb & 0x00FF00) >> 8);
271 }
272
273 /**
274 * Get the blue part of a packed rgb int.
275 *
276 * @param rgb a pixel in argb format
277 * @return just the blue part
278 */
279 public static final short getBlue(int rgb) {
280 return (short) ((rgb & 0x0000FF));
281 }
282
283 /**
284 * Adapter design pattern
285 *
286 * @param f a standard RGBImageFilter
287 * @return HppFilter3 Homogenious point processor
288 */
289 public static HppFilter3Interface getHppFilter3(final RGBImageFilter f) {
290 return new HppFilter3Interface() {
291 public short getR(int r, int g, int b) {
292 return getRed(f.filterRGB(0, 0, ImageUtils.packInt(r, g, b)));
293 }
294
295 public short getG(int r, int g, int b) {
296 return getGreen(f.filterRGB(0, 0, ImageUtils.packInt(r, g, b)));
297 }
298
299 public short getB(int r, int g, int b) {
300 return getBlue(f.filterRGB(0, 0, ImageUtils.packInt(r, g, b)));
301 }
302 };
303 }
304
305 public static RGBImageFilter getRGBImageFilter(final HppFilter3Interface f) {
306 return new RGBImageFilter() {
307 public int filterRGB(int x, int y, int rgb) {
308 Color c = new Color(rgb);
309 int r = c.getRed();
310 int g = c.getGreen();
311 int b = c.getBlue();
312 return packInt(f.getR(r, g, b),
313 f.getB(r, g, b),
314 f.getG(r, g, b));
315 }
316 };
317 }
318
319 private static int[] getPels(short r[][], short g[][], short b[][], HppFilterInterface f) {
320 int w = r.length;
321 int h = r[0].length;
322 int pels[] = new int[w * h];
323 for (int x = 0; x < w; x++)
324 for (int y = 0; y < h; y++)
325 pels[y + x * h] =
326 packInt(f.getR(r[x][y]),
327 f.getG(g[x][y]),
328 f.getB(b[x][y]));
329 return pels;
330 }
331
332 /**
333 * Return an int packed as ARGB
334 *
335 * @param r red component (0..255)
336 * @param g green component (0..255)
337 * @param b blue component (0..255)
338 * @return the packed int.
339 */
340 public static final int packInt(int r, int g, int b) {
341 return 0xFF000000
342 | ((0xFF & r) << 16)
343 | ((0xFF & g) << 8)
344 | (0xFF & b);
345 }
346
347 /**
348 * Get a convole operator instance from a <code>Kernel</code>
349 * instance.
350 *
351 * @param k The <code> kernel</code>instance
352 * @return an instance of a <code>ConvolveOp</code>.
353 */
354 public static ConvolveOp getConvolveOp(Kernel k) {
355 return new ConvolveOp(k, ConvolveOp.EDGE_ZERO_FILL, null);
356 }
357
358 public static Kernel makeKernel(int w, int h, float blurMatrix[]) {
359 return new Kernel(w, h, blurMatrix);
360 }
361
362 public static Kernel makeKernel(float k2d[][]) {
363 int w = k2d.length;
364 int h = k2d[0].length;
365 float k[] = new float[w * h];
366 int x = 0;
367 for (int i = 0; i < w; i++)
368 for (int j = 0; j < h; j++, x++)
369 k[x] = k2d[i][j];
370 return new Kernel(w, h, k);
371 }
372
373 public static boolean hasAlpha(Image image) {
374 // If buffered image, the color model is readily available
375 if (image instanceof BufferedImage) {
376 BufferedImage bimage = (BufferedImage) image;
377 return bimage.getColorModel().hasAlpha();
378 }
379
380 // Use a pixel grabber to retrieve the image's color model;
381 // grabbing a single pixel is usually sufficient
382 PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
383 try {
384 pg.grabPixels();
385 } catch (InterruptedException e) {
386 }
387
388 // Get the image's color model
389 ColorModel cm = pg.getColorModel();
390 return cm.hasAlpha();
391 }
392
393 public static BufferedImage getBufferedImage2(Image image) {
394 if (image instanceof BufferedImage) {
395 return (BufferedImage) image;
396 }
397
398 // This code ensures that all the pixels in the image are loaded
399 image = new ImageIcon(image).getImage();
400
401 // Determine if the image has transparent pixels; for this method's
402 // implementation, see e665 Determining If an Image Has Transparent Pixels
403 boolean hasAlpha = hasAlpha(image);
404 int w = image.getWidth(null);
405 int h = image.getHeight(null);
406
407 // Create a buffered image with a format that's compatible with the screen
408 BufferedImage bimage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
409 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
410 try {
411 // Determine the type of transparency of the new buffered image
412 int transparency = Transparency.OPAQUE;
413 if (hasAlpha) {
414 transparency = Transparency.BITMASK;
415 }
416
417 // Create the buffered image
418 GraphicsDevice gs = ge.getDefaultScreenDevice();
419 GraphicsConfiguration gc = gs.getDefaultConfiguration();
420 bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
421 } catch (Exception e) {
422 // The system does not have a screen
423 }
424
425 if (bimage == null) {
426 // Create a buffered image using the default color model
427 int type = BufferedImage.TYPE_INT_RGB;
428 if (hasAlpha) {
429 type = BufferedImage.TYPE_INT_ARGB;
430 }
431 bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
432 }
433
434 // Copy image to buffered image
435 Graphics g = bimage.createGraphics();
436
437 // Paint the image onto the buffered image
438 g.drawImage(image, 0, 0, null);
439 g.dispose();
440
441 return bimage;
442 }
443
444
445 public static BufferedImage getBufferedImage3(Image img) {
446 ImageBean ib = new ImageBean();
447 ib.setImage(img);
448 return getBufferedImage(ib);
449 }
450
451 public static BufferedImage getBufferedImage(Image img) {
452 int w = img.getWidth(null);
453 int h = img.getHeight(null);
454 BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
455 Graphics2D g2d = bi.createGraphics();
456 g2d.drawImage(img, 0, 0, w, h, null);
457 return bi;
458 }
459
460 public static BufferedImage getBufferedImage(ImageBeanInterface ib) {
461 int w = ib.getImageWidth();
462 int h = ib.getImageHeight();
463 BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
464 Graphics2D g2d = bi.createGraphics();
465 g2d.drawImage(ib.getImage(), 0, 0, w, h, null);
466 return bi;
467 }
468
469 public static ImageBean getImageBean(BufferedImage bi) {
470 ImageBean ib = new ImageBean();
471 ib.setImage(Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(bi.getSource(),
472 new BufferedImageFilter(new AffineTransformOp(new AffineTransform(),
473 AffineTransformOp.TYPE_BILINEAR)))));
474 return ib;
475 }
476
477 public static Image getImage(BufferedImage bi) {
478 return
479 Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(bi.getSource(),
480 new BufferedImageFilter(new AffineTransformOp(new AffineTransform(),
481 AffineTransformOp.TYPE_BILINEAR))));
482 }
483
484 public static ImageBean changeColors(float colorMatrix[][],
485 ImageBean ib) {
486 return getImageBean(changeColors(colorMatrix, getBufferedImage(ib)));
487 }
488
489 public static Image changeColors(float colorMatrix[][],
490 Image img) {
491 ImageBean ib = new ImageBean();
492 ib.setImage(img);
493 ib = changeColors(colorMatrix, ib);
494
495 return ib.getImage();
496 }
497
498
499 public static BufferedImage changeColors(float colorMatrix[][],
500 BufferedImage bi) {
501 // create filter to change colors
502 BandCombineOp bco =
503 new BandCombineOp(colorMatrix, null);
504
505 // create source and display Rasters
506 Raster inputRaster = bi.getRaster();
507
508 WritableRaster outputRaster =
509 inputRaster.createCompatibleWritableRaster();
510
511 // filter Rasters with changeColors filter
512 bco.filter(inputRaster, outputRaster);
513
514
515 // create new BufferedImage from display Raster
516 return new BufferedImage(bi.getColorModel(),
517 outputRaster, true, null);
518 }
519
520 public static ColorModel getRgbColorModel() {
521 return ColorModel.getRGBdefault();
522 }
523
524 public static void fitScreen(Component c) {
525 Toolkit tk = Toolkit.getDefaultToolkit();
526 Dimension d
527 = tk.getScreenSize();
528 c.setSize(d.width, d.height);
529 }
530
531 public static Image getImage(Image img, final HppFilterInterface f) {
532 RGBImageFilter rgbFilter = getRGBImageFilter(f);
533 ImageProducer ip = img.getSource();
534 ip = new FilteredImageSource(ip, rgbFilter);
535 Toolkit tk = Toolkit.getDefaultToolkit();
536 return tk.createImage(ip);
537 }
538
539 private static RGBImageFilter getRGBImageFilter(final HppFilterInterface f) {
540 return new RGBImageFilter() {
541 public int filterRGB(int x, int y, int rgb) {
542 Color c = new Color(rgb);
543 int r = f.getR(c.getRed());
544 int g = f.getG(c.getGreen());
545 int b = f.getB(c.getBlue());
546 return packInt(r, g, b);
547 }
548 };
549 }
550
551 public static Image getImage(int pels[], int w, int h) {
552 Toolkit tk = Toolkit.getDefaultToolkit();
553 return tk.createImage(new MemoryImageSource(w,
554 h,
555 getRgbColorModel(),
556 pels, 0,
557 w));
558 }
559
560 public static Image getImage(short r[][], short g[][], short b[][]) {
561 int w = r.length;
562 int h = r[0].length;
563 int pels[] = new int[w * h];
564 for (int x = 0; x < w; x++)
565 for (int y = 0; y < h; y++)
566 pels[x + y * w]
567 = 0xFF000000
568 | ((0xFF & r[x][y]) << 16)
569 | ((0xFF & g[x][y]) << 8)
570 | (0xFF & b[x][y]);
571 return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(w,
572 h,
573 ColorModel.getRGBdefault(),
574 pels, 0,
575 w));
576 }
577
578 public static int[] getPels(Image image) {
579 int w = image.getWidth(null);
580 int h = image.getHeight(null);
581 int pels[] = new int[w * h];
582
583 try {
584 new PixelGrabber(image, 0, 0,
585 w, h, pels, 0, w).grabPixels();
586 } catch (InterruptedException e) {
587 e.printStackTrace();
588 }
589 return pels;
590 }
591
592 public static int[] getPels(Image img, int width, int height) {
593 int pels[] = new int[width * height];
594
595 PixelGrabber grabber =
596 new PixelGrabber(img, 0, 0,
597 width, height, pels, 0, width);
598
599 try {
600 grabber.grabPixels();
601 } catch (InterruptedException e) {
602 }
603 return pels;
604 }
605
606 public static void pelsToShort(short r[][], short g[][], short b[][],
607 int[] pels, int width, int height) {
608 int i;
609 ColorModel cm = getRgbColorModel();
610 for (int x = 0; x < width; x++)
611 for (int y = 0; y < height; y++) {
612 i = x + y * width;
613 b[x][y] = (short) cm.getBlue(pels[i]);
614 g[x][y] = (short) cm.getGreen(pels[i]);
615 r[x][y] = (short) cm.getRed(pels[i]);
616 }
617 }
618
619 public static Image getGrayImage(short g[][]) {
620 Toolkit tk =
621 Toolkit.getDefaultToolkit();
622 ColorModel cm = tk.getColorModel();
623 int width = g.length;
624 int height = g[0].length;
625 int pels[] = new int[width * height];
626 for (int x = 0; x < width; x++)
627 for (int y = 0; y < height; y++) {
628 pels[x + y * width] =
629 0xff000000
630 | (g[y][x] << 16)
631 | (g[y][x] << 8)
632 | g[y][x];
633 }
634 return tk.createImage(new
635 MemoryImageSource(width,
636 height,
637 cm,
638 pels, 0,
639 width));
640 }
641
642 public static void writeHexImage(ImageBeanInterface ib) {
643 WriterUtil.writeString(getHexImage(ib));
644 }
645
646 public static String getHexImage(ImageBeanInterface ib) {
647 StringBuffer sb = new StringBuffer("");
648 int width = ib.getImageWidth();
649 int height = ib.getImageHeight();
650 Image img = ib.getImage();
651
652 int pixels[] = new int[width * height];
653 PixelGrabber pg = new PixelGrabber(img,
654 0,
655 0,
656 width,
657 height,
658 pixels,
659 0,
660 width);
661 try {
662 pg.grabPixels();
663 } catch (InterruptedException e) {
664 }
665 String newline = new String("\n");
666 int i = 0;
667 for (int y = 0; y < height; y++) {
668 for (int x = 0; x < width; x++) {
669 i = x + y * width;
670
671 sb.append("0x" + Integer.toHexString(pixels[i]) + ", ");
672 }
673 sb.append(newline);
674 }
675 return sb.toString();
676 }
677
678 public static Image getImage(short g[][]) {
679 if (g == null) return null;
680 int width = g.length;
681 int height = g[0].length;
682 Toolkit tk =
683 Toolkit.getDefaultToolkit();
684 ColorModel cm = tk.getColorModel();
685 int pels[] = new int[width * height];
686 for (int x = 0; x < width; x++)
687 for (int y = 0; y < height; y++) {
688 pels[x + y * width] =
689 0xff000000
690 | (g[x][y] << 16)
691 | (g[x][y] << 8)
692 | g[x][y];
693 }
694 return tk.createImage(new
695 MemoryImageSource(width,
696 height,
697 cm,
698 pels, 0,
699 width));
700 }
701
702 public static short[][] getGreenFromImage(Image img, ImageObserver io) {
703 if (img == null) return null;
704 int width = img.getWidth(io);
705 int height = img.getHeight(io);
706 int pels[] = new int[width * height];
707 ColorModel cm = ColorModel.getRGBdefault();
708
709 PixelGrabber grabber =
710 new PixelGrabber(img, 0, 0,
711 width, height, pels, 0, width);
712
713 try {
714 grabber.grabPixels();
715 } catch (InterruptedException e) {
716 }
717 ;
718 short g[][] = new short[width][height];
719 int i = 0;
720 for (int x = 0; x < width; x++)
721 for (int y = 0; y < height; y++) {
722 i = x + y * width;
723 g[x][y] = (short) cm.getGreen(pels[i]);
724 }
725 return g;
726 }
727
728 public static BufferedImage convolve(BufferedImage bi, float[][] blurMatrix) {
729 // create ConvolveOp for blurring BufferedImage
730 BufferedImageOp convolveOp =
731 getConvolveOp(makeKernel(blurMatrix));
732
733 // apply blurFilter to BufferedImage
734 return convolveOp.filter(bi, null);
735 }
736
737 public static Image convolution(Image img, float k[][]) {
738 return getImageBean(
739 convolve(getBufferedImage(img),
740 k)).getImage();
741
742 }
743
744 public static void print(Component c, String title) {
745 java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
746 java.awt.PrintJob pj =
747 tk.getPrintJob(new Frame(),
748 title,
749 null);
750 c.paint(pj.getGraphics());
751 pj.end();
752 }
753
754 public static void print(Component c) {
755 print(c, null);
756 }
757
758 public static Image combineBands(float ar,
759 float ag,
760 float ab,
761 Image img) {
762 HppFilter3ImageProcessor h3ip =
763 getLinearCombineBandsProcessor(ar, ag, ab);
764 return h3ip.process(img);
765 }
766
767 public static HppFilter3ImageProcessor
768 getLinearCombineBandsProcessor(float ar,
769 float ag,
770 float ab) {
771 return new HppFilter3ImageProcessor(new GreyHppFilter3(ar, ag, ab));
772 }
773
774
775 public static Image sobel(Image img) {
776 return convolution(img,
777 Kernels.getSobel());
778 }
779
780
781 public static void clip(short a[][], short min, short max) {
782 int w = a.length;
783 int h = a[0].length;
784 for (int x = 0; x < w; x++)
785 for (int y = 0; y < h; y++) {
786 if (a[x][y] < min) a[x][y] = min;
787 if (a[x][y] > max) a[x][y] = max;
788 }
789 }
790
791 /**
792 * pasteBean alters is bigOne argument
793 *
794 * @param littleOne a smaller image pasted into
795 * @param bigOne a bigger image
796 * @param x1 At this location
797 * @param y1
798 */
799 public static void pasteBean(ShortImageBean littleOne,
800 ShortImageBean bigOne,
801 int x1, int y1) {
802 int w = littleOne.getWidth();
803 int h = littleOne.getHeight();
804 int x2 = x1 + w;
805 int y2 = y1 + h;
806 int xd = 0;
807 int yd = 0;
808 short _r[][] = bigOne.getR();
809 short _g[][] = bigOne.getG();
810 short _b[][] = bigOne.getB();
811 for (int x = x1; x < x2; x++)
812 for (int y = y1; y < y2; y++) {
813 _r[x][y] = littleOne.getR()[xd][yd];
814 _g[x][y] = littleOne.getG()[xd][yd];
815 _b[x][y] = littleOne.getB()[xd][yd];
816 yd++;
817 }
818 yd = 0;
819 xd++;
820 }
821
822
823 public static ShortImageBean
824 cutBean(ShortImageBean sib,
825 int x1, int y1, int w, int h) {
826 int xd = 0;
827 int yd = 0;
828 int x2 = x1 + w;
829 int y2 = y1 + h;
830 ShortImageBean cutBean = new ShortImageBean(w, h);
831 short _r[][] = cutBean.getR();
832 short _g[][] = cutBean.getG();
833 short _b[][] = cutBean.getB();
834
835 for (int x = x1; x < x2; x++)
836 for (int y = y1; y < y2; y++) {
837 _r[xd][yd] = sib.getR()[x][y];
838 _g[xd][yd] = sib.getG()[x][y];
839 _b[xd][yd] = sib.getB()[x][y];
840 yd++;
841 }
842 yd = 0;
843 xd++;
844 return cutBean;
845 }
846
847 /**
848 * Compute the average image between img1 and img2.
849 *
850 * @param img1
851 * @param img2
852 * @return average image
853 */
854 public static Image average(Image img1, Image img2) {
855 ShortImageBean sib1 = new ShortImageBean(img1);
856 ShortImageBean sib2 = new ShortImageBean(img2);
857 sib1.average(sib2);
858 return sib1.getImage();
859 }
860
861 /**
862 * Computer the average image from the image array, ia.
863 *
864 * @param ia
865 * @return average image.
866 */
867 public static Image average(Image ia[]) {
868 ShortImageBean sib1 = new ShortImageBean(ia[0]);
869 for (int i = 1; i < ia.length; i++) {
870 ShortImageBean sib2 = new ShortImageBean(ia[i]);
871 sib1.average(sib2);
872 }
873 return sib1.getImage();
874 }
875
876 public static Image getImageResource(Window w, String iconFileName) {
877 return w.getToolkit().getImage(w.getClass().getResource("images/" + iconFileName));
878 }
879
880 public static Image getImageResource(Object o, String iconFileName) {
881 Toolkit tk = Toolkit.getDefaultToolkit();
882 return tk.getImage(o.getClass().getResource("images/" + iconFileName));
883 }
884
885 /**
886 * Helper function to load an icon image from the JAR file of which
887 * this class is a part.
888 */
889 public static ImageIcon fetchIcon(Window w,
890 String iconFileName) {
891 return new ImageIcon(getImageResource(w, iconFileName));
892 }
893
894 public static void main(String args[]) {
895 testListProperties();
896 }
897
898 private static void testListProperties() {
899 final Toolkit tk = Toolkit.getDefaultToolkit();
900
901 final String propertyName = //"win.propNames";
902 "";
903 String propnames[] = (String[]) tk
904 .getDesktopProperty(propertyName);
905 System.out.println("Supported windows property names:");
906 for (int i = 0; i < propnames.length; i++) {
907 System.out.println(propnames[i]);
908 }
909
910 }
911
912 public static void saveAsGif(Image img, File f) {
913 try {
914 ip.vs.WriteGIF.DoIt(img, f + "");
915 } catch (IOException e) {
916 e.printStackTrace();
917 } catch (AWTException e) {
918 e.printStackTrace();
919 }
920 }
921
922 public static StreamSniffer openAndSniffFile() {
923 String fn = Futil.getReadFileName();
924 InputStream is;
925 if (fn == null) return null;
926 try {
927 is = new FileInputStream(fn);
928 } catch (FileNotFoundException e) {
929 return null;
930 }
931 StreamSniffer ss = new StreamSniffer(is);
932 System.out.println("Hmm, this smells like a " + ss);
933 System.out.println("The id is :" + ss.classifyStream());
934 return ss;
935 }
936
937 public static Dimension readPpmImageHeader(InputStream in)
938 throws IOException {
939 char c1, c2;
940
941 c1 = (char) readByte(in);
942 c2 = (char) readByte(in);
943
944 if (c1 != 'P') {
945 throw new IOException("not a PPM file");
946 }
947 if (c2 != '6') {
948 throw new IOException("not a PPM file");
949 }
950
951 int width1 = readInt(in);
952 int height1 = readInt(in);
953
954 // Read maximum value of each color, and ignore it.
955 // In PPM_RAW we know r,g,b use full range (0-255).
956 readInt(in);
957 return new Dimension(width1, height1);
958 }
959
960 public static int readInt(InputStream in)
961 throws IOException {
962 char c;
963 int i;
964
965 c = readNonwhiteChar(in);
966 if ((c < '0') || (c > '9')) {
967 throw new IOException("Invalid integer when reading PPM image file.");
968 }
969
970 i = 0;
971 do {
972 i = i * 10 + c - '0';
973 c = readChar(in);
974 } while ((c >= '0') && (c <= '9'));
975
976 return (i);
977 }
978
979 public static int readByte(InputStream in)
980 throws IOException {
981 int b = in.read();
982
983 // if end of file
984 if (b == -1) {
985 throw new EOFException();
986 }
987 return b;
988 }
989
990 public static char readNonwhiteChar(InputStream in)
991 throws IOException {
992 char c;
993
994 do {
995 c = readChar(in);
996 } while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
997
998 return c;
999 }
1000
1001 public static char readChar(InputStream in)
1002 throws IOException {
1003 char c;
1004
1005 c = (char) readByte(in);
1006 if (c == '#') {
1007 do {
1008 c = (char) readByte(in);
1009 } while ((c != '\n') && (c != '\r'));
1010 }
1011
1012 return c;
1013 }
1014
1015 public static Image gaussian(int kernelWidth, double sigma, Image img) {
1016
1017 ImageProcessorInterface ipi =
1018 new GaussianSmoothingProcessor(kernelWidth, sigma);
1019 return ipi.process(img);
1020 }
1021
1022 public static Image negate(Image img) {
1023 ImageProcessorInterface ipi = InvertFilter.getProcessor();
1024 return ipi.process(img);
1025 }
1026
1027 public static Image threshold(Image img, double b) {
1028 Threshold3Processor t3p = new Threshold3Processor(b);
1029 return t3p.process(img);
1030 }
1031 public static Image enahe(double alpha, Image img){
1032 EnaheFilter e = new EnaheFilter(img, alpha / 10.0);
1033 return new HppFilterImageProcessor(e).process(img);
1034 }
1035 public static Image unahe(Image img) {
1036 EqualizationFilter cf = new EqualizationFilter(img);
1037 HppFilterImageProcessor hip = new HppFilterImageProcessor(cf);
1038 return hip.process(img);
1039 }
1040
1041 public static Image smooth(int kernelWidth, double sigma, Image image) {
1042 GaussianSmoothingProcessor gsp =
1043 new GaussianSmoothingProcessor(kernelWidth, sigma);
1044 return gsp.process(image);
1045 }
1046
1047 public static Image colorize(double ar, double ag, double ab, Image img) {
1048 PseudoColorFilter pcf = new PseudoColorFilter(ar, ag, ab);
1049 HppFilterImageProcessor hip = new HppFilterImageProcessor(pcf);
1050 return hip.process(img);
1051 }
1052
1053 public static Image getContrastBrightnessAdjustedImage(double c, double b, Image img) {
1054 ContrastFilter cf = new ContrastFilter(c, b);
1055 HppFilterImageProcessor hpp = new HppFilterImageProcessor(cf);
1056 return hpp.process((img));
1057 }
1058
1059 // - - Here is the BLogic.....
1060 public static Image getImage(File f) throws FileNotFoundException {
1061 FileInputStream fis =
1062 new FileInputStream(f);
1063 int type = getType(fis);
1064 if (type == StreamSniffer.GIF87a)
1065 return getGifJpgPngImage(f);
1066 if (type == StreamSniffer.GIF89a)
1067 return getGifJpgPngImage(f);
1068 if (type == StreamSniffer.JPEG)
1069 return getGifJpgPngImage(f);
1070 if (type == StreamSniffer.JPG)
1071 return getGifJpgPngImage(f);
1072 if (type == StreamSniffer.PNG_IMAGE)
1073 return getGifJpgPngImage(f);
1074 Futil.close(fis);
1075 return null;
1076 }
1077
1078 public static int getType(FileInputStream fis) {
1079 StreamSniffer ss =
1080 new StreamSniffer(fis);
1081 return ss.classifyStream();
1082 }
1083
1084 public static void testSniff() {
1085 FileInputStream fis =
1086 Futil.getFileInputStream("select a new data file");
1087 StreamSniffer ss =
1088 new StreamSniffer(fis);
1089
1090 System.out.println("fee fi fo fum I smell:" + ss);
1091 Futil.close(fis);
1092 }
1093
1094 public static void saveAsGif(Image img, String fn) {
1095 try {
1096 ip.vs.WriteGIF.DoIt(img,
1097 fn);
1098 } catch (Exception e) {
1099 e.printStackTrace();
1100 }
1101 }
1102 /**
1103 * Captures the entire screen
1104 * @return SreenImage
1105 * @throws AWTException
1106 */
1107 public static BufferedImage captureWholeScreen() throws AWTException {
1108 return new Robot().createScreenCapture(
1109 new Rectangle(Toolkit.getDefaultToolkit()
1110 .getScreenSize()));
1111 }
1112
1113 public static BufferedImage captureScreen(Component c)
1114 throws AWTException {
1115 return new Robot().createScreenCapture(new Rectangle(c.getX(), c.getY(),
1116 c.getWidth(), c.getHeight()));
1117 }
1118
1119 public static Rectangle getScreenSize() {
1120 Toolkit tk = Toolkit.getDefaultToolkit();
1121 return new Rectangle(tk.getScreenSize());
1122 }
1123 /**
1124 * Fast scaling of a buffered image by using replicated pixels.
1125 * Used the Image.scale method with a Image.SCALE_FAST for
1126 * fastest possible result.
1127 * If either the <code>width</code>
1128 * or <code>height</code> is a negative number then a value is
1129 * substituted to maintain the aspect ratio of the original image
1130 * dimensions.
1131 * @param bi
1132 * @param width
1133 * @param height
1134 * @return
1135 */
1136 public static BufferedImage scaleFast(BufferedImage bi, int width, int height){
1137 Image img = getImage(bi);
1138 img = scaleFast(img,width,height);
1139 return ImageUtils.getBufferedImage(img);
1140 }
1141 /**
1142 * Uses the Image.SCALE_FAST rendering hint to make use of replicated
1143 * pixels for creating the new image. No averaging here...
1144 * If either the <code>width</code>
1145 * or <code>height</code> is a negative number then a value is
1146 * substituted to maintain the aspect ratio of the original image
1147 * dimensions.
1148 * @param img
1149 * @param width
1150 * @param height
1151 * @return
1152 */
1153 public static Image scaleFast(Image img,int width,int height){
1154 return img.getScaledInstance(width,height,Image.SCALE_FAST);
1155 }
1156
1157 public static String getImageIoFormat() {
1158 return (String) In.multiPrompt(
1159 getImageIOFormatNames(),
1160 "select an output format", "format selector dialog");
1161 }
1162
1163 public static String[] getImageIOFormatNames() {
1164 final String[] writerFormatNames =
1165 ImageIO.getWriterFormatNames();
1166 return writerFormatNames;
1167 }
1168 /**
1169 * The following code does not seem to work on a mac.
1170 * I dont know why.
1171 * @param bi
1172 * @param f
1173 * @throws IOException
1174 */
1175 public static void saveAsTiff(BufferedImage bi, File f)
1176 throws IOException {
1177 OutputStream os = new FileOutputStream(f);
1178 TIFFEncodeParam tep = new TIFFEncodeParam();
1179 ImageEncoder encoder= ImageCodec.createImageEncoder("TIFF",os,tep);
1180 encoder.encode(bi);
1181 os.close();
1182 }
1183
1184 /**
1185 * grab a screen capture in png format.
1186 *
1187 * @param rect
1188 * @throws java.awt.AWTException
1189 * @throws java.io.IOException
1190 */
1191 public static byte[] grabAPngImage(Rectangle rect)
1192 throws AWTException, IOException {
1193 // create screen shot
1194 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1195 Robot robot = new Robot();
1196 BufferedImage image = robot.createScreenCapture(rect);
1197 // save captured image to PNG file
1198 ImageIO.write(image, "png", baos);
1199 baos.close();
1200 return baos.toByteArray();
1201 }
1202
1203 private static class imagePanel extends JPanel {
1204 private final Image img;
1205
1206 public imagePanel(Image img) {
1207 this.img = img;
1208 setLayout(new FlowLayout());
1209 }
1210
1211 public void paint(Graphics g) {
1212 Dimension d = getSize();
1213 g.drawImage(img, 0, 0, d.width, d.height, this);
1214 }
1215
1216 public Dimension getPreferredSize() {
1217 return new Dimension(img.getWidth(this),
1218 img.getHeight(this));
1219 }
1220 }
1221
1222 public static void saveAsPPM(Image img, String fn) {
1223 ShortImageBean sib = new ShortImageBean(img);
1224 WritePPM.doIt(sib.getR(),
1225 sib.getG(),
1226 sib.getB(),
1227 fn);
1228 }
1229
1230 }
1231