Coverage details for edu.uci.ics.jung.visualization.FourPassImageShaper

LineHitsSource
1 /*
2  * Copyright (c) 2005, the JUNG Project and the Regents of the University of
3  * California All rights reserved.
4  *
5  * This software is open-source under the BSD license; see either "license.txt"
6  * or http://jung.sourceforge.net/license.txt for a description.
7  *
8  * Created on Jun 17, 2005
9  */
10  
11 package edu.uci.ics.jung.visualization;
12  
13 import java.awt.Graphics;
14 import java.awt.Graphics2D;
15 import java.awt.Image;
16 import java.awt.Shape;
17 import java.awt.geom.AffineTransform;
18 import java.awt.geom.Area;
19 import java.awt.geom.GeneralPath;
20 import java.awt.geom.Line2D;
21 import java.awt.geom.Point2D;
22 import java.awt.image.BufferedImage;
23 import java.io.IOException;
24  
25 import javax.imageio.ImageIO;
26  
27 /**
28  * Provides factory methods that, given a BufferedImage, an Image,
29  * or the fileName of an image, will return a java.awt.Shape that
30  * is the contiguous traced outline of the opaque part of the image.
31  * This could be used to define an image for use in a Vertex, where
32  * the shape used for picking and edge-arrow placement follows the
33  * opaque part of an image that has a transparent background.
34  * The methods try to detect lines in order to minimize points
35  * in the path
36  *
37  * @author Tom Nelson - RABA Technologies
38  *
39  *
40  */
410public class FourPassImageShaper {
42     
43     /**
44      * given the fileName of an image, possibly with a transparent
45      * background, return the Shape of the opaque part of the image
46      * @param fileName name of the image, loaded from the classpath
47      * @return the Shape
48      */
49     public static Shape getShape(String fileName) {
500        return getShape(fileName, Integer.MAX_VALUE);
51     }
52     public static Shape getShape(String fileName, int max) {
530        BufferedImage image = null;
54         try {
550            image = ImageIO.read(FourPassImageShaper.class.getResource(fileName));
560        } catch(IOException ex) {
570            ex.printStackTrace();
580        }
590        return getShape(image, max);
60     }
61     
62     /**
63      * Given an image, possibly with a transparent background, return
64      * the Shape of the opaque part of the image
65      * @param image
66      * @return the Shape
67      */
68     public static Shape getShape(Image image) {
690        return getShape(image, Integer.MAX_VALUE);
70     }
71     public static Shape getShape(Image image, int max) {
720        BufferedImage bi =
73             new BufferedImage(image.getWidth(null), image.getHeight(null),
74                     BufferedImage.TYPE_INT_ARGB);
750        Graphics g = bi.createGraphics();
760        g.drawImage(image, 0, 0, null);
770        g.dispose();
780        return getShape(bi, max);
79     }
80     
81     /**
82      * Given an image, possibly with a transparent background, return
83      * the Shape of the opaque part of the image
84      *
85      * If the image is larger than max in either direction, scale the
86      * image down to max-by-max, do the trace (on fewer points) then
87      * scale the resulting shape back up to the size of the original
88      * image.
89      *
90      * @param image the image to trace
91      * @param max used to restrict number of points in the resulting shape
92      * @return the Shape
93      */
94     public static Shape getShape(BufferedImage image, int max) {
95         
960        float width = image.getWidth();
970        float height = image.getHeight();
980        if(width > max || height > max) {
990            BufferedImage smaller =
100                 new BufferedImage(max, max, BufferedImage.TYPE_INT_ARGB);
1010            Graphics g = smaller.createGraphics();
1020            AffineTransform at = AffineTransform.getScaleInstance(max/width,max/height);
1030            AffineTransform back = AffineTransform.getScaleInstance(width/max,height/max);
1040            Graphics2D g2 = (Graphics2D)g;
1050            g2.drawImage(image, at, null);
1060            g2.dispose();
1070            return back.createTransformedShape(getShape(smaller));
108         } else {
1090            return getShape(image);
110         }
111     }
112     
113     public static Shape getShape(BufferedImage image) {
1140        Area area = new Area(leftEdge(image));
1150        area.intersect(new Area(bottomEdge(image)));
1160        area.intersect(new Area(rightEdge(image)));
1170        area.intersect(new Area(topEdge(image)));
1180        return area;
119     }
120     /**
121      * Checks to see if point p is on a line that passes thru
122      * points p1 and p2. If p is on the line, extend the line
123      * segment so that it is from p1 to the location of p.
124      * If the point p is not on the line, update my shape
125      * with a line extending to the old p2 location, make
126      * the old p2 the new p1, and make p2 the old p
127      * @param p1
128      * @param p2
129      * @param p
130      * @param line
131      * @param path
132      * @return
133      */
134     private static Point2D detectLine(Point2D p1, Point2D p2, Point2D p,
135             Line2D line, GeneralPath path) {
1360        if(p2 == null) {
1370            p2 = p;
1380            line.setLine(p1,p2);
139         }
140         // check for line
1410        else if(line.ptLineDistSq(p) < 1) { // its on the line
142             // make it p2
1430            p2.setLocation(p);
144         } else { // its not on the current line
1450            p1.setLocation(p2);
1460            p2.setLocation(p);
1470            line.setLine(p1,p2);
1480            path.lineTo((float)p1.getX(), (float)p1.getY());
149         }
1500        return p2;
151     }
152     /**
153      * trace the left side of the image
154      * @param image
155      * @param path
156      * @return
157      */
158     private static Shape leftEdge(BufferedImage image) {
1590        GeneralPath path = new GeneralPath();
1600        Point2D p1 = new Point2D.Float(image.getWidth()-1, 0);
1610        Point2D p2 = null;
1620        Line2D line = new Line2D.Float();
1630        Point2D p = new Point2D.Float();
1640        path.moveTo(image.getWidth()-1, 0);
165         
1660        for(int i=0; i<image.getHeight(); i++) {
1670            p.setLocation(image.getWidth()-1, i);
168             // go until we reach an opaque point, then stop
1690            for(int j=0; j<image.getWidth(); j++) {
1700                if((image.getRGB(j,i) & 0xff000000) != 0) {
171                     // this is a point I want
1720                    p.setLocation(j,i);
1730                    break;
174                 }
175             }
1760            p2 = detectLine(p1, p2, p, line, path);
177         }
1780        p.setLocation(image.getWidth()-1, image.getHeight()-1);
1790        detectLine(p1, p2, p, line, path);
1800        path.closePath();
1810        return path;
182     }
183     
184     /**
185      * trace the bottom of the image
186      * @param image
187      * @param path
188      * @param start
189      * @return
190      */
191     private static Shape bottomEdge(BufferedImage image) {
1920        GeneralPath path = new GeneralPath();
1930        Point2D p1 = new Point2D.Float(0, 0);
1940        Point2D p2 = null;
1950        Line2D line = new Line2D.Float();
1960        Point2D p = new Point2D.Float();
1970        path.moveTo(0, 0);
1980        for(int i=0; i<image.getWidth(); i++) {
1990            p.setLocation(i, 0);
2000            for(int j=image.getHeight()-1; j>=0; j--) {
2010                if((image.getRGB(i,j) & 0xff000000) != 0) {
202                     // this is a point I want
2030                    p.setLocation(i,j);
2040                    break;
205                 }
206             }
2070            p2 = detectLine(p1, p2, p, line, path);
208         }
2090        p.setLocation(image.getWidth()-1, 0);
2100        detectLine(p1, p2, p, line, path);
2110        path.closePath();
2120        return path;
213     }
214     
215     /**
216      * trace the right side of the image
217      * @param image
218      * @param path
219      * @param start
220      * @return
221      */
222     private static Shape rightEdge(BufferedImage image) {
2230        GeneralPath path = new GeneralPath();
2240        Point2D p1 = new Point2D.Float(0, image.getHeight()-1);
2250        Point2D p2 = null;
2260        Line2D line = new Line2D.Float();
2270        Point2D p = new Point2D.Float();
2280        path.moveTo(0, image.getHeight()-1);
229         
2300        for(int i=image.getHeight()-1; i>=0; i--) {
2310            p.setLocation(0, i);
2320            for(int j=image.getWidth()-1; j>=0; j--) {
2330                if((image.getRGB(j,i) & 0xff000000) != 0) {
234                     // this is a point I want
2350                    p.setLocation(j,i);
2360                    break;
237                 }
238             }
2390            p2 = detectLine(p1, p2, p, line, path);
240         }
2410        p.setLocation(0, 0);
2420        detectLine(p1, p2, p,line, path);
2430        path.closePath();
2440        return path;
245     }
246     
247     /**
248      * trace the top of the image
249      * @param image
250      * @param path
251      * @param start
252      * @return
253      */
254     private static Shape topEdge(BufferedImage image) {
2550        GeneralPath path = new GeneralPath();
2560        Point2D p1 = new Point2D.Float(image.getWidth()-1, image.getHeight()-1);
2570        Point2D p2 = null;
2580        Line2D line = new Line2D.Float();
2590        Point2D p = new Point2D.Float();
2600        path.moveTo(image.getWidth()-1, image.getHeight()-1);
261         
2620        for(int i=image.getWidth()-1; i>=0; i--) {
2630            p.setLocation(i, image.getHeight()-1);
2640            for(int j=0; j<image.getHeight(); j++) {
2650                if((image.getRGB(i,j) & 0xff000000) != 0) {
266                     // this is a point I want
2670                    p.setLocation(i,j);
2680                    break;
269                 }
270             }
2710            p2 = detectLine(p1, p2, p, line, path);
272         }
2730        p.setLocation(0, image.getHeight()-1);
2740        detectLine(p1, p2, p, line, path);
2750        path.closePath();
2760        return path;
277     }
278 }

this report was generated by version 1.0.5 of jcoverage.
visit www.jcoverage.com for updates.

copyright © 2003, jcoverage ltd. all rights reserved.
Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.