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
26
27
28
29
30 package org.openimaj.image.renderer;
31
32 import java.util.Arrays;
33
34 import org.openimaj.image.FImage;
35 import org.openimaj.image.ImageUtilities;
36 import org.openimaj.image.MBFImage;
37
38
39
40
41
42
43
44 public class MBFImageRenderer extends MultiBandRenderer<Float, MBFImage, FImage> {
45
46
47
48
49
50
51
52 public MBFImageRenderer(final MBFImage targetImage) {
53 super(targetImage);
54 }
55
56
57
58
59
60
61
62
63
64 public MBFImageRenderer(final MBFImage targetImage, final RenderHints hints) {
65 super(targetImage, hints);
66 }
67
68 @Override
69 public Float[] defaultBackgroundColour() {
70 return new Float[this.targetImage.numBands()];
71 }
72
73 @Override
74 public Float[] defaultForegroundColour() {
75 final Float[] c = new Float[this.targetImage.numBands()];
76 Arrays.fill(c, 1f);
77 return c;
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91 @Override
92 public void drawImage(final MBFImage image, final int x, final int y) {
93 final int targetBands = this.targetImage.numBands();
94 final int imageBands = image.numBands();
95
96 if (targetBands == imageBands && targetBands == 3) {
97 this.drawImage3(image, x, y);
98 return;
99 } else if (targetBands < 3 || targetBands > 4 || imageBands < 3 || imageBands > 4) {
100 super.drawImage(image, x, y);
101 return;
102 }
103
104 final int stopx = Math.min(this.targetImage.getWidth(), x + image.getWidth());
105 final int stopy = Math.min(this.targetImage.getHeight(), y + image.getHeight());
106 final int startx = Math.max(0, x);
107 final int starty = Math.max(0, y);
108
109 final float[][][] thisPixels = new float[targetBands][][];
110 for (int i = 0; i < thisPixels.length; i++)
111 thisPixels[i] = this.targetImage.getBand(i).pixels;
112
113 final float[][][] thatPixels = new float[imageBands][][];
114 for (int i = 0; i < thatPixels.length; i++)
115 thatPixels[i] = image.getBand(i).pixels;
116
117
118
119
120
121
122
123 if(thisPixels.length == 4 && thatPixels.length == 4){
124 drawBothAlpha(x, y, stopx, stopy, startx, starty, thisPixels, thatPixels);
125 } else if (thisPixels.length == 4){
126 drawThisAlpha(x, y, stopx, stopy, startx, starty, thisPixels, thatPixels);
127 } else{
128 drawThatAlpha(x, y, stopx, stopy, startx, starty, thisPixels, thatPixels);
129 }
130 }
131
132 private void drawBothAlpha(final int x, final int y, final int stopx,
133 final int stopy, final int startx, final int starty,
134 final float[][][] thisPixels, final float[][][] thatPixels) {
135 float[] out = new float[4];
136 for (int yy = starty; yy < stopy; yy++) {
137 final int thatY = yy - y;
138
139 for (int xx = startx; xx < stopx; xx++) {
140
141 final int thatX = xx - x;
142 float thisA = thisPixels[3][yy][xx] ;
143 float thatA = thatPixels[3][thatY][thatX] ;
144 ImageUtilities.alphaCompositePixel(out,
145 thisPixels[0][yy][xx], thisPixels[1][yy][xx], thisPixels[2][yy][xx], thisA,
146 thatPixels[0][thatY][thatX], thatPixels[1][thatY][thatX], thatPixels[2][thatY][thatX], thatA
147 );
148
149 thisPixels[0][yy][xx] = out[0];
150 thisPixels[1][yy][xx] = out[1];
151 thisPixels[2][yy][xx] = out[2];
152 thisPixels[3][yy][xx] = out[3];
153 }
154 }
155 }
156
157 private void drawThisAlpha(final int x, final int y, final int stopx,
158 final int stopy, final int startx, final int starty,
159 final float[][][] thisPixels, final float[][][] thatPixels) {
160 float[] out = new float[4];
161 for (int yy = starty; yy < stopy; yy++) {
162 final int thatY = yy - y;
163
164 for (int xx = startx; xx < stopx; xx++) {
165
166 final int thatX = xx - x;
167 float thisA = thisPixels[3][yy][xx] ;
168 float thatA = 1f ;
169 ImageUtilities.alphaCompositePixel(out,
170 thisPixels[0][yy][xx], thisPixels[1][yy][xx], thisPixels[2][yy][xx], thisA,
171 thatPixels[0][thatY][thatX], thatPixels[1][thatY][thatX], thatPixels[2][thatY][thatX], thatA
172 );
173
174 thisPixels[0][yy][xx] = out[0];
175 thisPixels[1][yy][xx] = out[1];
176 thisPixels[2][yy][xx] = out[2];
177 thisPixels[3][yy][xx] = out[3];
178 }
179 }
180 }
181
182 private void drawThatAlpha(final int x, final int y, final int stopx,
183 final int stopy, final int startx, final int starty,
184 final float[][][] thisPixels, final float[][][] thatPixels) {
185 float[] out = new float[4];
186 for (int yy = starty; yy < stopy; yy++) {
187 final int thatY = yy - y;
188
189 for (int xx = startx; xx < stopx; xx++) {
190
191 final int thatX = xx - x;
192 float thisA = 1f ;
193 float thatA = thatPixels[3][thatY][thatX] ;
194 ImageUtilities.alphaCompositePixel(out,
195 thisPixels[0][yy][xx], thisPixels[1][yy][xx], thisPixels[2][yy][xx], thisA,
196 thatPixels[0][thatY][thatX], thatPixels[1][thatY][thatX], thatPixels[2][thatY][thatX], thatA
197 );
198
199 thisPixels[0][yy][xx] = out[0];
200 thisPixels[1][yy][xx] = out[1];
201 thisPixels[2][yy][xx] = out[2];
202 }
203 }
204 }
205
206 protected void drawImage3(final MBFImage image, final int x, final int y) {
207 final int stopx = Math.max(0, Math.min(this.targetImage.getWidth(), x + image.getWidth()));
208 final int stopy = Math.max(0, Math.min(this.targetImage.getHeight(), y + image.getHeight()));
209 final int startx = Math.max(0, x);
210 final int starty = Math.max(0, y);
211
212 if (startx >= stopx || starty >= stopy)
213 return;
214
215 final float[][][] thisPixels = new float[3][][];
216 for (int i = 0; i < thisPixels.length; i++)
217 thisPixels[i] = this.targetImage.getBand(i).pixels;
218
219 final float[][][] thatPixels = new float[3][][];
220 for (int i = 0; i < thatPixels.length; i++)
221 thatPixels[i] = image.getBand(i).pixels;
222
223 for (int yy = starty; yy < stopy; yy++) {
224 final int thatY = yy - y;
225
226 System.arraycopy(thatPixels[0][thatY], startx - x, thisPixels[0][yy], startx, stopx - startx);
227 System.arraycopy(thatPixels[1][thatY], startx - x, thisPixels[1][yy], startx, stopx - startx);
228 System.arraycopy(thatPixels[2][thatY], startx - x, thisPixels[2][yy], startx, stopx - startx);
229
230
231
232
233
234
235
236
237
238 }
239 }
240
241 @Override
242 protected void drawHorizLine(final int x1, final int x2, final int y, Float[] col) {
243 col = this.sanitise(col);
244 if (y < 0 || y > this.targetImage.getHeight() - 1)
245 return;
246
247 final int startx = Math.max(0, Math.min(x1, x2));
248 final int stopx = Math.min(Math.max(x1, x2), this.targetImage.getWidth() - 1);
249 final int nbands = Math.min(col.length, this.targetImage.numBands());
250
251 for (int b = 0; b < nbands; b++) {
252 final float[][] img = this.targetImage.getBand(b).pixels;
253 final float c = col[b];
254
255 for (int x = startx; x <= stopx; x++) {
256 img[y][x] = c;
257 }
258 }
259 }
260
261 @Override
262 protected Float[] sanitise(final Float[] colour)
263 {
264 return this.targetImage.colourSpace.sanitise(colour);
265 }
266 }