This project has retired. For details please refer to its
Attic page.
ImageSlicer xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.chukwa.hicc;
19
20 import java.awt.Graphics;
21 import java.awt.geom.AffineTransform;
22 import java.awt.image.AffineTransformOp;
23 import java.awt.image.BufferedImage;
24 import java.io.File;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29
30 import javax.imageio.ImageIO;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.chukwa.util.ExceptionUtil;
35
36 public class ImageSlicer {
37 private BufferedImage src = null;
38 private Log log = LogFactory.getLog(ImageSlicer.class);
39 private String sandbox = System.getenv("CHUKWA_HOME")+File.separator+"webapps"+File.separator+"sandbox"+File.separator;
40 private int maxLevel = 0;
41
42 public ImageSlicer() {
43 }
44
45
46
47
48
49
50
51
52
53 public BufferedImage prepare(String filename) {
54 try {
55 src = ImageIO.read(new File(filename));
56 } catch (IOException e) {
57 log.error("Image file does not exist:"+filename+", can not render image.");
58 }
59 XYData fullSize = new XYData(1, 1);
60 while(fullSize.getX()<src.getWidth() || fullSize.getY()<src.getHeight()) {
61 fullSize.set(fullSize.getX()*2, fullSize.getY()*2);
62 }
63 float scaleX = (float)fullSize.getX()/src.getWidth();
64 float scaleY = (float)fullSize.getY()/src.getHeight();
65 log.info("Image size: ("+src.getWidth()+","+src.getHeight()+")");
66 log.info("Scale size: ("+scaleX+","+scaleY+")");
67
68 AffineTransform at =
69 AffineTransform.getScaleInstance(scaleX,scaleY);
70
71
72 AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
73 BufferedImage dest = op.filter(src, null);
74 return dest;
75 }
76
77
78
79
80
81
82
83
84
85
86 public BufferedImage tile(BufferedImage image, int level, XYData quadrant, XYData size, boolean efficient) throws Exception {
87 double scale = Math.pow(2, level);
88 if(efficient) {
89
90 XYData inverSize = new XYData((int)(image.getWidth(null)/(size.getX()*scale)),
91 (int)(image.getHeight(null)/(size.getY()*scale)));
92 XYData topLeft = new XYData(quadrant.getX()*size.getX()*inverSize.getX(),
93 quadrant.getY()*size.getY()*inverSize.getY());
94 XYData newSize = new XYData((size.getX()*inverSize.getX()),
95 (size.getY()*inverSize.getY()));
96 if(inverSize.getX()<1.0 || inverSize.getY() < 1.0) {
97 throw new Exception("Requested zoom level ("+level+") is too high.");
98 }
99 image = image.getSubimage(topLeft.getX(), topLeft.getY(), newSize.getX(), newSize.getY());
100 BufferedImage zoomed = new BufferedImage(size.getX(), size.getY(), BufferedImage.TYPE_INT_RGB);
101 zoomed.getGraphics().drawImage(image, 0, 0, size.getX(), size.getY(), null);
102 if(level>maxLevel) {
103 maxLevel = level;
104 }
105 return zoomed;
106 } else {
107
108 XYData newSize = new XYData((int)(size.getX()*scale), (int)(size.getY()*scale));
109 XYData topLeft = new XYData(quadrant.getX()*size.getX(), quadrant.getY()*size.getY());
110 if(newSize.getX() > image.getWidth(null) || newSize.getY() > image.getHeight(null)) {
111 throw new Exception("Requested zoom level ("+level+") is too high.");
112 }
113 AffineTransform tx = new AffineTransform();
114 AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
115 tx.scale(scale, scale);
116 image = op.filter(image, null);
117 BufferedImage zoomed = image.getSubimage(topLeft.getX(), topLeft.getY(), newSize.getX(), newSize.getY());
118 if(level>maxLevel) {
119 maxLevel = level;
120 }
121 return zoomed;
122 }
123 }
124
125
126
127
128
129
130
131
132
133
134
135 public BufferedImage subdivide(BufferedImage image, int level, XYData quadrant, XYData size, String prefix) {
136 if(image.getWidth()<=size.getX()*Math.pow(2, level)) {
137 try {
138 BufferedImage outputImage = tile(image, level, quadrant, size, true);
139 write(outputImage, level, quadrant, prefix);
140 return outputImage;
141 } catch (Exception e) {
142 log.error(ExceptionUtil.getStackTrace(e));
143 }
144 }
145
146 BufferedImage zoomed = new BufferedImage(size.getX()*2, size.getY()*2, BufferedImage.TYPE_INT_RGB);
147 Graphics g = zoomed.getGraphics();
148 XYData newQuadrant = new XYData(quadrant.getX() * 2 + 0, quadrant.getY() * 2 + 0);
149 g.drawImage(subdivide(image, level+1, newQuadrant, size, prefix), 0, 0, null);
150 newQuadrant = new XYData(quadrant.getX()*2 + 0, quadrant.getY()*2 + 1);
151 g.drawImage(subdivide(image, level+1, newQuadrant, size, prefix), 0, size.getY(), null);
152 newQuadrant = new XYData(quadrant.getX()*2 + 1, quadrant.getY()*2 + 0);
153 g.drawImage(subdivide(image, level+1, newQuadrant, size, prefix), size.getX(), 0, null);
154 newQuadrant = new XYData(quadrant.getX()*2 + 1, quadrant.getY()*2 + 1);
155 g.drawImage(subdivide(image, level+1, newQuadrant, size, prefix), size.getX(), size.getY(), null);
156 BufferedImage outputImage = new BufferedImage(size.getX(), size.getY(), BufferedImage.TYPE_INT_RGB);
157 outputImage.getGraphics().drawImage(zoomed, 0, 0, size.getX(), size.getY(), null);
158 write(outputImage, level, quadrant, prefix);
159 return outputImage;
160 }
161
162
163
164
165 public void write(BufferedImage image, int level, XYData quadrant, String prefix) {
166 StringBuilder outputFile = new StringBuilder();
167 outputFile.append(sandbox);
168 outputFile.append(File.separator);
169 outputFile.append(prefix);
170 outputFile.append("-");
171 outputFile.append(level);
172 outputFile.append("-");
173 outputFile.append(quadrant.getX());
174 outputFile.append("-");
175 outputFile.append(quadrant.getY());
176 outputFile.append(".png");
177 FileOutputStream fos;
178 try {
179 fos = new FileOutputStream(outputFile.toString());
180 ImageIO.write(image, "PNG", fos);
181 fos.close();
182 } catch (IOException e) {
183 log.error(ExceptionUtil.getStackTrace(e));
184 }
185 }
186
187 public int process(String filename) {
188 Pattern p = Pattern.compile("(.*)\\.(.*)");
189 Matcher m = p.matcher(filename);
190 if(m.matches()) {
191 String prefix = m.group(1);
192 String fullPath = sandbox + File.separator + filename;
193 subdivide(prepare(fullPath), 0, new XYData(0, 0), new XYData(256, 256), prefix);
194 return maxLevel;
195 }
196 return 0;
197 }
198
199 }
200
201 class XYData {
202 private int x = 0;
203 private int y = 0;
204
205 public XYData(int x, int y) {
206 this.x=x;
207 this.y=y;
208 }
209
210 public void set(int x, int y) {
211 this.x=x;
212 this.y=y;
213 }
214
215 public int getX() {
216 return x;
217 }
218
219 public int getY() {
220 return y;
221 }
222
223 }