1 | sclass RGBImage implements MakesBufferedImage, IRGBImage { |
2 | transient BufferedImage bufferedImage; |
3 | File file; |
4 | int width, height; |
5 | int[] pixels; |
6 | |
7 | *() {} |
8 | |
9 | *(BufferedImage image) { |
10 | this(image, null); |
11 | } |
12 | |
13 | *(BufferedImage image, File file) { |
14 | this.file = file; |
15 | bufferedImage = image; |
16 | width = image.getWidth(); |
17 | height = image.getHeight(); |
18 | pixels = new int[width*height]; |
19 | PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width); |
20 | try { |
21 | if (!pixelGrabber.grabPixels()) |
22 | throw new RuntimeException("Could not grab pixels"); |
23 | cleanPixels(); // set upper byte to 0 |
24 | } catch (InterruptedException e) { |
25 | throw new RuntimeException(e); |
26 | } |
27 | } |
28 | |
29 | /** We assume it's a file name to load from */ |
30 | *(String file) throws IOException { |
31 | this(new File(file)); |
32 | } |
33 | |
34 | *(Dimension size, Color color) { |
35 | this(size.width, size.height, color); |
36 | } |
37 | |
38 | *(Dimension size, RGB color) { |
39 | this(size.width, size.height, color); |
40 | } |
41 | |
42 | private void cleanPixels() { |
43 | for (int i = 0; i < pixels.length; i++) |
44 | pixels[i] &= 0xFFFFFF; |
45 | } |
46 | |
47 | *(int width, int height, int[] pixels) { |
48 | this.width = width; |
49 | this.height = height; |
50 | this.pixels = pixels; |
51 | } |
52 | |
53 | *(int w, int h, RGB[] pixels) { |
54 | this.width = w; |
55 | this.height = h; |
56 | this.pixels = asInts(pixels); |
57 | } |
58 | |
59 | public static int[] asInts(RGB[] pixels) { |
60 | int[] ints = new int[pixels.length]; |
61 | for (int i = 0; i < pixels.length; i++) |
62 | ints[i] = pixels[i] == null ? 0 : pixels[i].getColor().getRGB(); |
63 | return ints; |
64 | } |
65 | |
66 | public RGBImage(int w, int h) { |
67 | this(w, h, Color.black); |
68 | } |
69 | |
70 | *(int w, int h, RGB rgb) { |
71 | this.width = w; |
72 | this.height = h; |
73 | this.pixels = new int[w*h]; |
74 | int col = rgb.asInt(); |
75 | if (col != 0) |
76 | for (int i = 0; i < pixels.length; i++) |
77 | pixels[i] = col; |
78 | } |
79 | |
80 | *(RGBImage image) { |
81 | this(image.width, image.height, copyPixels(image.pixels)); |
82 | } |
83 | |
84 | *(int width, int height, Color color) { |
85 | this(width, height, new RGB(color)); |
86 | } |
87 | |
88 | *(File file) throws IOException { |
89 | this(javax.imageio.ImageIO.read(file)); |
90 | } |
91 | |
92 | *(MakesBufferedImage img) { |
93 | this(toBufferedImage(img)); |
94 | } |
95 | |
96 | private static int[] copyPixels(int[] pixels) { |
97 | int[] copy = new int[pixels.length]; |
98 | System.arraycopy(pixels, 0, copy, 0, pixels.length); |
99 | return copy; |
100 | } |
101 | |
102 | public int getIntPixel(int x, int y) { |
103 | if (inRange(x, y)) |
104 | return pixels[y * width + x]; |
105 | else |
106 | return 0xFFFFFF; |
107 | } |
108 | |
109 | public static RGB asRGB(int packed) { |
110 | int r = (packed >> 16) & 0xFF; |
111 | int g = (packed >> 8) & 0xFF; |
112 | int b = packed & 0xFF; |
113 | return new RGB(r / 255f, g / 255f, b / 255f); |
114 | } |
115 | |
116 | public RGB getRGB(int x, int y) { |
117 | if (inRange(x, y)) |
118 | return asRGB(pixels[y * width + x]); |
119 | else |
120 | return new RGB(0xFFFFFF); |
121 | } |
122 | |
123 | /** alias of getRGB - I kept typing getPixel instead of getRGB all the time, so I finally created it */ |
124 | RGB getPixel(int x, int y) { |
125 | return getRGB(x, y); |
126 | } |
127 | |
128 | RGB getPixel(Pt p) { ret getPixel(p.x, p.y); } |
129 | |
130 | public int getWidth() { return width; } |
131 | public int getHeight() { return height; } |
132 | public int w() { ret width; } |
133 | public int h() { ret height; } |
134 | |
135 | /** Attention: cached, i.e. does not change when image itself changes */ |
136 | /** @NotNull */ |
137 | public BufferedImage getBufferedImage() { |
138 | if (bufferedImage == null) { |
139 | bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
140 | //bufferedImage.setData(Raster.createRaster(new SampleModel())); |
141 | for (int y = 0; y < height; y++) |
142 | for (int x = 0; x < width; x++) |
143 | bufferedImage.setRGB(x, y, pixels[y*width+x]); |
144 | } |
145 | return bufferedImage; |
146 | } |
147 | |
148 | RGBImage clip(Rect r) { |
149 | ret r == null ? null : clip(r.getRectangle()); |
150 | } |
151 | |
152 | RGBImage clip(Rectangle r) { |
153 | r = fixClipRect(r); |
154 | if (r.x == 0 && r.y == 0 && r.width == width && r.height == height) this; |
155 | int[] newPixels; |
156 | try { |
157 | newPixels = new int[r.width*r.height]; |
158 | } catch (RuntimeException e) { |
159 | System.out.println(r); |
160 | throw e; |
161 | } |
162 | for (int y = 0; y < r.height; y++) { |
163 | System.arraycopy(pixels, (y+r.y)*width+r.x, newPixels, y*r.width, r.width); |
164 | } |
165 | return new RGBImage(r.width, r.height, newPixels); |
166 | } |
167 | |
168 | private Rectangle fixClipRect(Rectangle r) { |
169 | r = r.intersection(new Rectangle(0, 0, width, height)); |
170 | if (r.isEmpty()) |
171 | r = new Rectangle(r.x, r.y, 0, 0); |
172 | return r; |
173 | } |
174 | |
175 | public File getFile() { |
176 | return file; |
177 | } |
178 | |
179 | /** can now also do GIF (not just JPEG) */ |
180 | public static RGBImage load(String fileName) { |
181 | return load(new File(fileName)); |
182 | } |
183 | |
184 | /** can now also do GIF (not just JPEG) */ |
185 | public static RGBImage load(File file) { |
186 | try { |
187 | BufferedImage bufferedImage = javax.imageio.ImageIO.read(file); |
188 | return new RGBImage(bufferedImage); |
189 | } catch (IOException e) { |
190 | throw new RuntimeException(e); |
191 | } |
192 | } |
193 | |
194 | public int getInt(int x, int y) { |
195 | return pixels[y * width + x]; |
196 | } |
197 | |
198 | public void save(File file) throws IOException { |
199 | String name = file.getName().toLowerCase(); |
200 | String type; |
201 | if (name.endsWith(".png")) type = "png"; |
202 | else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) type = "jpeg"; |
203 | else throw new IOException("Unknown image extension: " + name); |
204 | javax.imageio.ImageIO.write(getBufferedImage(), type, file); |
205 | } |
206 | |
207 | public static RGBImage dummyImage() { |
208 | return new RGBImage(1, 1, new int[] {0xFFFFFF}); |
209 | } |
210 | |
211 | public int[] getPixels() { |
212 | return pixels; |
213 | } |
214 | |
215 | void setPixel(int x, int y, int r, int g, int b) { |
216 | if (x >= 0 && y >= 0 && x < width && y < height) |
217 | pixels[y*width+x] = (limitToUByte(r) << 16) | (limitToUByte(g) << 8) | limitToUByte(b); |
218 | } |
219 | |
220 | public void setPixel(int x, int y, RGB rgb) { |
221 | if (x >= 0 && y >= 0 && x < width && y < height) |
222 | pixels[y*width+x] = rgb.asInt(); |
223 | } |
224 | |
225 | public void setPixel aka set(int x, int y, Color color) { |
226 | setPixel(x, y, new RGB(color)); |
227 | } |
228 | |
229 | void setInt(int x, int y, int rgb) { |
230 | setPixel(x, y, rgb); |
231 | } |
232 | |
233 | public void setPixel(int x, int y, int rgb) { |
234 | if (x >= 0 && y >= 0 && x < width && y < height) |
235 | pixels[y*width+x] = rgb; |
236 | } |
237 | |
238 | void setPixel(Pt p, RGB rgb) { setPixel(p.x, p.y, rgb); } |
239 | void setPixel(Pt p, Color color) { setPixel(p.x, p.y, color); } |
240 | |
241 | public RGBImage copy() { |
242 | return new RGBImage(this); |
243 | } |
244 | |
245 | public boolean inRange(int x, int y) { |
246 | return x >= 0 && y >= 0 && x < width && y < height; |
247 | } |
248 | |
249 | public Dimension getSize() { |
250 | return new Dimension(width, height); |
251 | } |
252 | |
253 | @Override |
254 | public boolean equals(Object o) { |
255 | if (this == o) return true; |
256 | if (o == null || getClass() != o.getClass()) return false; |
257 | |
258 | RGBImage rgbImage = (RGBImage) o; |
259 | |
260 | if (height != rgbImage.height) return false; |
261 | if (width != rgbImage.width) return false; |
262 | if (!Arrays.equals(pixels, rgbImage.pixels)) return false; |
263 | |
264 | return true; |
265 | } |
266 | |
267 | @Override |
268 | public int hashCode() { |
269 | int result = width; |
270 | result = 31 * result + height; |
271 | result = 31 * result + Arrays.hashCode(pixels); |
272 | return result; |
273 | } |
274 | |
275 | public String getHex(int x, int y) { |
276 | return getPixel(x, y).getHexString(); |
277 | } |
278 | |
279 | public RGBImage clip(int x, int y, int width, int height) { |
280 | return clip(new Rectangle(x, y, width, height)); |
281 | } |
282 | |
283 | public RGBImage clipLine(int y) { |
284 | return clip(0, y, width, 1); |
285 | } |
286 | |
287 | public int numPixels() { |
288 | return width*height; |
289 | } |
290 | |
291 | void uncacheBufferedImage { |
292 | bufferedImage = null; |
293 | } |
294 | } |
Began life as a copy of #1002470
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1034522 |
Snippet name: | RGBImage backup |
Eternal ID of this version: | #1034522/1 |
Text MD5: | 0a09cc730f93612b6bc1320506400493 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-02-10 07:46:32 |
Source code size: | 7821 bytes / 294 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 142 / 158 |
Referenced in: | [show references] |