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