1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.jrobin.graph;
26
27 import com.sun.image.codec.jpeg.JPEGCodec;
28 import com.sun.image.codec.jpeg.JPEGEncodeParam;
29 import com.sun.image.codec.jpeg.JPEGImageEncoder;
30
31 import javax.imageio.ImageIO;
32 import java.awt.*;
33 import java.awt.font.LineMetrics;
34 import java.awt.geom.AffineTransform;
35 import java.awt.image.BufferedImage;
36 import java.io.*;
37
38 class ImageWorker {
39 private static final String DUMMY_TEXT = "Dummy";
40
41 private BufferedImage img;
42 private Graphics2D gd;
43 private int imgWidth, imgHeight;
44 private AffineTransform aftInitial;
45
46 ImageWorker(int width, int height) {
47 resize(width, height);
48 }
49
50 void resize(int width, int height) {
51 if (gd != null) {
52 gd.dispose();
53 }
54 this.imgWidth = width;
55 this.imgHeight = height;
56 this.img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
57 this.gd = img.createGraphics();
58 this.aftInitial = gd.getTransform();
59 this.setAntiAliasing(false);
60 }
61
62 void clip(int x, int y, int width, int height) {
63 gd.setClip(x, y, width, height);
64 }
65
66 void transform(int x, int y, double angle) {
67 gd.translate(x, y);
68 gd.rotate(angle);
69 }
70
71 void reset() {
72 gd.setTransform(aftInitial);
73 gd.setClip(0, 0, imgWidth, imgHeight);
74 }
75
76 void fillRect(int x, int y, int width, int height, Paint paint) {
77 gd.setPaint(paint);
78 gd.fillRect(x, y, width, height);
79 }
80
81 void fillPolygon(int[] x, int[] y, Paint paint) {
82 gd.setPaint(paint);
83 gd.fillPolygon(x, y, x.length);
84 }
85
86 void fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint) {
87 gd.setPaint(paint);
88 PathIterator path = new PathIterator(yTop);
89 for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
90 int start = pos[0], end = pos[1], n = end - start;
91 int[] xDev = new int[n + 2], yDev = new int[n + 2];
92 for (int i = start; i < end; i++) {
93 xDev[i - start] = (int) x[i];
94 yDev[i - start] = (int) yTop[i];
95 }
96 xDev[n] = xDev[n - 1];
97 xDev[n + 1] = xDev[0];
98 yDev[n] = yDev[n + 1] = (int) yBottom;
99 gd.fillPolygon(xDev, yDev, xDev.length);
100 gd.drawPolygon(xDev, yDev, xDev.length);
101 }
102 }
103
104 void fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint) {
105 gd.setPaint(paint);
106 PathIterator path = new PathIterator(yTop);
107 for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
108 int start = pos[0], end = pos[1], n = end - start;
109 int[] xDev = new int[n * 2], yDev = new int[n * 2];
110 for (int i = start; i < end; i++) {
111 int ix1 = i - start, ix2 = n * 2 - 1 - i + start;
112 xDev[ix1] = xDev[ix2] = (int) x[i];
113 yDev[ix1] = (int) yTop[i];
114 yDev[ix2] = (int) yBottom[i];
115 }
116 gd.fillPolygon(xDev, yDev, xDev.length);
117 gd.drawPolygon(xDev, yDev, xDev.length);
118 }
119 }
120
121
122 void drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke) {
123 gd.setStroke(stroke);
124 gd.setPaint(paint);
125 gd.drawLine(x1, y1, x2, y2);
126 }
127
128 void drawPolyline(int[] x, int[] y, Paint paint, Stroke stroke) {
129 gd.setStroke(stroke);
130 gd.setPaint(paint);
131 gd.drawPolyline(x, y, x.length);
132 }
133
134 void drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke) {
135 gd.setPaint(paint);
136 gd.setStroke(stroke);
137 PathIterator path = new PathIterator(y);
138 for (int[] pos = path.getNextPath(); pos != null; pos = path.getNextPath()) {
139 int start = pos[0], end = pos[1];
140 int[] xDev = new int[end - start], yDev = new int[end - start];
141 for (int i = start; i < end; i++) {
142 xDev[i - start] = (int) x[i];
143 yDev[i - start] = (int) y[i];
144 }
145 gd.drawPolyline(xDev, yDev, xDev.length);
146 }
147 }
148
149 void drawString(String text, int x, int y, Font font, Paint paint) {
150 gd.setFont(font);
151 gd.setPaint(paint);
152 gd.drawString(text, x, y);
153 }
154
155 double getFontAscent(Font font) {
156 LineMetrics lm = font.getLineMetrics(DUMMY_TEXT, gd.getFontRenderContext());
157 return lm.getAscent();
158 }
159
160 double getFontHeight(Font font) {
161 LineMetrics lm = font.getLineMetrics(DUMMY_TEXT, gd.getFontRenderContext());
162 return lm.getAscent() + lm.getDescent();
163 }
164
165 double getStringWidth(String text, Font font) {
166 return font.getStringBounds(text, 0, text.length(), gd.getFontRenderContext()).getBounds().getWidth();
167 }
168
169 void setAntiAliasing(boolean enable) {
170 gd.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
171 enable ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
172 gd.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
173 gd.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
174 }
175
176 void dispose() {
177 gd.dispose();
178 }
179
180 void saveImage(OutputStream stream, String type, float quality) throws IOException {
181 if (type.equalsIgnoreCase("png")) {
182 ImageIO.write(img, "png", stream);
183 }
184 else if (type.equalsIgnoreCase("gif")) {
185 GifEncoder gifEncoder = new GifEncoder(img);
186 gifEncoder.encode(stream);
187 }
188 else if (type.equalsIgnoreCase("jpg") || type.equalsIgnoreCase("jpeg")) {
189 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(stream);
190 JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(img);
191 param.setQuality(quality, false);
192 encoder.setJPEGEncodeParam(param);
193 encoder.encode(img);
194 }
195 else {
196 throw new IOException("Unsupported image format: " + type);
197 }
198 stream.flush();
199 }
200
201 byte[] saveImage(String path, String type, float quality) throws IOException {
202 byte[] bytes = getImageBytes(type, quality);
203 RandomAccessFile f = new RandomAccessFile(path, "rw");
204 try {
205 f.write(bytes);
206 return bytes;
207 }
208 finally {
209 f.close();
210 }
211 }
212
213 byte[] getImageBytes(String type, float quality) throws IOException {
214 ByteArrayOutputStream stream = new ByteArrayOutputStream();
215 try {
216 saveImage(stream, type, quality);
217 return stream.toByteArray();
218 }
219 finally {
220 stream.close();
221 }
222 }
223
224 public void loadImage(String imageFile) throws IOException {
225 BufferedImage wpImage = ImageIO.read(new File(imageFile));
226 TexturePaint paint = new TexturePaint(wpImage, new Rectangle(0, 0, wpImage.getWidth(), wpImage.getHeight()));
227 gd.setPaint(paint);
228 gd.fillRect(0, 0, wpImage.getWidth(), wpImage.getHeight());
229 }
230 }