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

Line | Hits | Source
--- | --- | ---
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 |  | `*/`
41 | 0 | `public 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) {`
50 | 0 | `return getShape(fileName, Integer.MAX_VALUE);`
51 |  | `}`
52 |  | `public static Shape getShape(String fileName, int max) {`
53 | 0 | `BufferedImage image = null;`
54 |  | `try {`
55 | 0 | `image = ImageIO.read(FourPassImageShaper.class.getResource(fileName));`
56 | 0 | `} catch(IOException ex) {`
57 | 0 | `ex.printStackTrace();`
58 | 0 | `}`
59 | 0 | `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) {`
69 | 0 | `return getShape(image, Integer.MAX_VALUE);`
70 |  | `}`
71 |  | `public static Shape getShape(Image image, int max) {`
72 | 0 | `BufferedImage bi =`
73 |  | `new BufferedImage(image.getWidth(null), image.getHeight(null),`
74 |  | `BufferedImage.TYPE_INT_ARGB);`
75 | 0 | `Graphics g = bi.createGraphics();`
76 | 0 | `g.drawImage(image, 0, 0, null);`
77 | 0 | `g.dispose();`
78 | 0 | `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 |  | ``
96 | 0 | `float width = image.getWidth();`
97 | 0 | `float height = image.getHeight();`
98 | 0 | `if(width > max || height > max) {`
99 | 0 | `BufferedImage smaller =`
100 |  | `new BufferedImage(max, max, BufferedImage.TYPE_INT_ARGB);`
101 | 0 | `Graphics g = smaller.createGraphics();`
102 | 0 | `AffineTransform at = AffineTransform.getScaleInstance(max/width,max/height);`
103 | 0 | `AffineTransform back = AffineTransform.getScaleInstance(width/max,height/max);`
104 | 0 | `Graphics2D g2 = (Graphics2D)g;`
105 | 0 | `g2.drawImage(image, at, null);`
106 | 0 | `g2.dispose();`
107 | 0 | `return back.createTransformedShape(getShape(smaller));`
108 |  | `} else {`
109 | 0 | `return getShape(image);`
110 |  | `}`
111 |  | `}`
112 |  | ``
113 |  | `public static Shape getShape(BufferedImage image) {`
114 | 0 | `Area area = new Area(leftEdge(image));`
115 | 0 | `area.intersect(new Area(bottomEdge(image)));`
116 | 0 | `area.intersect(new Area(rightEdge(image)));`
117 | 0 | `area.intersect(new Area(topEdge(image)));`
118 | 0 | `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) {`
136 | 0 | `if(p2 == null) {`
137 | 0 | `p2 = p;`
138 | 0 | `line.setLine(p1,p2);`
139 |  | `}`
140 |  | `// check for line`
141 | 0 | `else if(line.ptLineDistSq(p) < 1) { // its on the line`
142 |  | `// make it p2`
143 | 0 | `p2.setLocation(p);`
144 |  | `} else { // its not on the current line`
145 | 0 | `p1.setLocation(p2);`
146 | 0 | `p2.setLocation(p);`
147 | 0 | `line.setLine(p1,p2);`
148 | 0 | `path.lineTo((float)p1.getX(), (float)p1.getY());`
149 |  | `}`
150 | 0 | `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) {`
159 | 0 | `GeneralPath path = new GeneralPath();`
160 | 0 | `Point2D p1 = new Point2D.Float(image.getWidth()-1, 0);`
161 | 0 | `Point2D p2 = null;`
162 | 0 | `Line2D line = new Line2D.Float();`
163 | 0 | `Point2D p = new Point2D.Float();`
164 | 0 | `path.moveTo(image.getWidth()-1, 0);`
165 |  | ``
166 | 0 | `for(int i=0; i<image.getHeight(); i++) {`
167 | 0 | `p.setLocation(image.getWidth()-1, i);`
168 |  | `// go until we reach an opaque point, then stop`
169 | 0 | `for(int j=0; j<image.getWidth(); j++) {`
170 | 0 | `if((image.getRGB(j,i) & 0xff000000) != 0) {`
171 |  | `// this is a point I want`
172 | 0 | `p.setLocation(j,i);`
173 | 0 | `break;`
174 |  | `}`
175 |  | `}`
176 | 0 | `p2 = detectLine(p1, p2, p, line, path);`
177 |  | `}`
178 | 0 | `p.setLocation(image.getWidth()-1, image.getHeight()-1);`
179 | 0 | `detectLine(p1, p2, p, line, path);`
180 | 0 | `path.closePath();`
181 | 0 | `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) {`
192 | 0 | `GeneralPath path = new GeneralPath();`
193 | 0 | `Point2D p1 = new Point2D.Float(0, 0);`
194 | 0 | `Point2D p2 = null;`
195 | 0 | `Line2D line = new Line2D.Float();`
196 | 0 | `Point2D p = new Point2D.Float();`
197 | 0 | `path.moveTo(0, 0);`
198 | 0 | `for(int i=0; i<image.getWidth(); i++) {`
199 | 0 | `p.setLocation(i, 0);`
200 | 0 | `for(int j=image.getHeight()-1; j>=0; j--) {`
201 | 0 | `if((image.getRGB(i,j) & 0xff000000) != 0) {`
202 |  | `// this is a point I want`
203 | 0 | `p.setLocation(i,j);`
204 | 0 | `break;`
205 |  | `}`
206 |  | `}`
207 | 0 | `p2 = detectLine(p1, p2, p, line, path);`
208 |  | `}`
209 | 0 | `p.setLocation(image.getWidth()-1, 0);`
210 | 0 | `detectLine(p1, p2, p, line, path);`
211 | 0 | `path.closePath();`
212 | 0 | `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) {`
223 | 0 | `GeneralPath path = new GeneralPath();`
224 | 0 | `Point2D p1 = new Point2D.Float(0, image.getHeight()-1);`
225 | 0 | `Point2D p2 = null;`
226 | 0 | `Line2D line = new Line2D.Float();`
227 | 0 | `Point2D p = new Point2D.Float();`
228 | 0 | `path.moveTo(0, image.getHeight()-1);`
229 |  | ``
230 | 0 | `for(int i=image.getHeight()-1; i>=0; i--) {`
231 | 0 | `p.setLocation(0, i);`
232 | 0 | `for(int j=image.getWidth()-1; j>=0; j--) {`
233 | 0 | `if((image.getRGB(j,i) & 0xff000000) != 0) {`
234 |  | `// this is a point I want`
235 | 0 | `p.setLocation(j,i);`
236 | 0 | `break;`
237 |  | `}`
238 |  | `}`
239 | 0 | `p2 = detectLine(p1, p2, p, line, path);`
240 |  | `}`
241 | 0 | `p.setLocation(0, 0);`
242 | 0 | `detectLine(p1, p2, p,line, path);`
243 | 0 | `path.closePath();`
244 | 0 | `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) {`
255 | 0 | `GeneralPath path = new GeneralPath();`
256 | 0 | `Point2D p1 = new Point2D.Float(image.getWidth()-1, image.getHeight()-1);`
257 | 0 | `Point2D p2 = null;`
258 | 0 | `Line2D line = new Line2D.Float();`
259 | 0 | `Point2D p = new Point2D.Float();`
260 | 0 | `path.moveTo(image.getWidth()-1, image.getHeight()-1);`
261 |  | ``
262 | 0 | `for(int i=image.getWidth()-1; i>=0; i--) {`
263 | 0 | `p.setLocation(i, image.getHeight()-1);`
264 | 0 | `for(int j=0; j<image.getHeight(); j++) {`
265 | 0 | `if((image.getRGB(i,j) & 0xff000000) != 0) {`
266 |  | `// this is a point I want`
267 | 0 | `p.setLocation(i,j);`
268 | 0 | `break;`
269 |  | `}`
270 |  | `}`
271 | 0 | `p2 = detectLine(p1, p2, p, line, path);`
272 |  | `}`
273 | 0 | `p.setLocation(0, image.getHeight()-1);`
274 | 0 | `detectLine(p1, p2, p, line, path);`
275 | 0 | `path.closePath();`
276 | 0 | `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.