Blimp v.0.2 (2004-11-10)
Christian Heimke authored 13 years ago
|
1) /* BlinkenLightsInteractiveMovieProgram
|
Blimp v.1.1 (2005-04-16)
Christian Heimke authored 13 years ago
|
2) * version 1.1 date 2005-04-16
|
Blimp v.0.6 (2005-03-10)
Christian Heimke authored 13 years ago
|
3) * Copyright (C) 2004-2005: Stefan Schuermans <1stein@schuermans.info>
|
Blimp v.0.2 (2004-11-10)
Christian Heimke authored 13 years ago
|
4) * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5) * a blinkenarea.org project
6) * powered by eventphone.de
7) */
8)
9) import java.awt.*;
10)
11) public class BlinkenFrame
12) {
13)
14) private int height;
15) private int width;
16) private int channels;
17) private int maxval;
18) private int duration;
19) private byte[][][] data;
20)
21) BlinkenFrame( int height, int width, int channels, int maxval, int duration )
22) {
23) if( height < 1 ) height = 1;
24) if( height > 1024 ) height = 1024;
25) if( width < 1 ) width = 1;
26) if( width > 1024 ) width = 1024;
27) if( channels < 1 ) channels = 1;
28) if( channels > 16 ) channels = 16;
29) if( maxval < 1 ) maxval = 1;
30) if( maxval > 255 ) maxval = 255;
31) if( duration < 1 ) duration = 1;
32) if( duration > 65535 ) duration = 65535;
33)
34) this.height = height;
35) this.width = width;
36) this.channels = channels;
37) this.maxval = maxval;
38) this.duration = duration;
39) data = new byte[height][width][channels];
40) }
41)
42) BlinkenFrame( BlinkenFrame frame )
43) {
44) int y, x, c;
45) height = frame.height;
46) width = frame.width;
47) channels = frame.channels;
48) maxval = frame.maxval;
49) duration = frame.duration;
50) data = new byte[height][width][channels];
51) for( y = 0; y < height; y++ )
52) for( x = 0; x < width; x++ )
53) for( c = 0; c < channels; c++ )
54) data[y][x][c] = frame.data[y][x][c];
55) }
56)
57) public void clear( )
58) {
59) int x, y, c;
60) for( y = 0; y < height; y++ )
61) for( x = 0; x < width; x++ )
62) for( c = 0; c < channels; c++ )
63) data[y][x][c] = 0;
64) }
65)
66) public int getHeight( )
67) {
68) return height;
69) }
70)
71) public int getWidth( )
72) {
73) return width;
74) }
75)
76) public int getChannels( )
77) {
78) return channels;
79) }
80)
81) public int getMaxval( )
82) {
83) return maxval;
84) }
85)
86) public int getDuration( )
87) {
88) return duration;
89) }
90)
91) public void setDuration( int duration )
92) {
93) if( duration < 1 ) duration = 1;
94) if( duration > 65535 ) duration = 65535;
95) this.duration = duration;
96) }
97)
98) public byte getPixel( int y, int x, int c )
99) {
100) if( y < 0 || y >= height ||
101) x < 0 || x >= width ||
102) c < 0 || c >= channels )
103) return 0;
104) return data[y][x][c];
105) }
106)
107) public void setPixel( int y, int x, int c, byte val )
108) {
109) if( y < 0 || y >= height ||
110) x < 0 || x >= width ||
111) c < 0 || c >= channels )
112) return;
113) if( val > maxval )
114) val = (byte)maxval;
115) data[y][x][c] = val;
116) }
117)
118) public Color getColor( int y, int x )
119) {
120) if( y < 0 || y >= height ||
121) x < 0 || x >= width ||
122) channels < 1 )
123) return new Color( 0, 0, 0 );
124) if( channels == 1 )
125) return new Color( (((int)data[y][x][0] & 0xFF) * 255 + maxval / 2) / maxval,
126) (((int)data[y][x][0] & 0xFF) * 255 + maxval / 2) / maxval,
127) (((int)data[y][x][0] & 0xFF) * 255 + maxval / 2) / maxval );
128) if( channels == 2 )
129) return new Color( (((int)data[y][x][0] & 0xFF) * 255 + maxval / 2) / maxval,
130) (((int)data[y][x][1] & 0xFF) * 255 + maxval / 2) / maxval, 0 );
131) return new Color( (((int)data[y][x][0] & 0xFF) * 255 + maxval / 2) / maxval,
132) (((int)data[y][x][1] & 0xFF) * 255 + maxval / 2) / maxval,
133) (((int)data[y][x][2] & 0xFF) * 255 + maxval / 2) / maxval );
134) }
135)
136) public void setColor( int y, int x, Color color )
137) {
138) int alpha, alpha_, c;
139) if( y < 0 || y >= height ||
140) x < 0 || x >= width )
141) return;
142) alpha = color.getAlpha( );
143) alpha_ = 255 - alpha;
144) if( channels >= 1 )
145) data[y][x][0] = (byte)(( ((color.getRed( ) * maxval + 127) / 255) * alpha
146) + ((int)data[y][x][0] & 0xFF) * alpha_
147) ) / 255);
148) if( channels >= 2 )
149) data[y][x][1] = (byte)(( ((color.getGreen( ) * maxval + 127) / 255) * alpha
150) + ((int)data[y][x][1] & 0xFF) * alpha_
151) ) / 255);
152) if( channels >= 3 )
153) data[y][x][2] = (byte)(( ((color.getBlue( ) * maxval + 127) / 255) * alpha
154) + ((int)data[y][x][2] & 0xFF) * alpha_
155) ) / 255);
156) for( c = 3; c < channels; c++ )
157) data[y][x][c] = (byte)(( 0
|
Blimp v.0.5 (2004-11-19)
Christian Heimke authored 13 years ago
|
158) + ((int)data[y][x][c] & 0xFF) * alpha_
|
Blimp v.0.2 (2004-11-10)
Christian Heimke authored 13 years ago
|
159) ) / 255);
160) }
161)
162) public void resize( int height, int width, int channels, int maxval )
163) {
164) byte[][][] data;
165) int y, x, c;
166) int emptyY, emptyX, skipY, skipX, rangeY, rangeX, val, div;
167)
168) if( height < 1 ) height = 1;
169) if( height > 1024 ) height = 1024;
170) if( width < 1 ) width = 1;
171) if( width > 1024 ) width = 1024;
172) if( channels < 1 ) channels = 1;
173) if( channels > 16 ) channels = 16;
174) if( maxval < 1 ) maxval = 1;
175) if( maxval > 255 ) maxval = 255;
176)
177) if( height == this.height &&
178) width == this.width &&
179) channels == this.channels &&
180) maxval == this.maxval )
181) return;
182)
183) //allocate new data array
184) data = new byte[height][width][channels];
185) for( y = 0; y < height; y++ )
186) for( x = 0; x < width; x++ )
187) for( c = 0; c < channels; c++ )
188) data[y][x][c] = 0;
189)
190) //get number of pixels to skip / to leave empty in X and Y direction
191) if( height > this.height )
192) {
193) emptyY = (height - this.height) / 2;
194) skipY = 0;
195) rangeY = this.height;
196) }
197) else
198) {
199) emptyY = 0;
200) skipY = (this.height - height) / 2;
201) rangeY = height;
202) }
203) if( width > this.width )
204) {
205) emptyX = (width - this.width) / 2;
206) skipX = 0;
207) rangeX = this.width;
208) }
209) else
210) {
211) emptyX = 0;
212) skipX = (this.width - width) / 2;
213) rangeX = width;
214) }
215)
216) //resize frame with help of calculated parameters
217) for( y = 0; y < rangeY; y++ )
218) {
219) for( x = 0; x < rangeX; x++ )
220) {
221) if( channels >= this.channels ) //add channels: copy last channel into new channels
222) {
223) for( c = 0; c < this.channels; c++ )
224) data[emptyY + y][emptyX + x][c] = (byte)((((int)this.data[skipY + y][skipX + x][c] & 0xFF) * maxval + this.maxval / 2) / this.maxval);
225) for( ; c < channels; c++ )
226) data[emptyY + y][emptyX + x][c] = data[emptyY + y][emptyX + x][this.channels - 1];
227) }
228) else //remove channels: merge leftover channels with last kept channel
229) {
230) val = 0;
231) for( c = 0; c < channels - 1; c++ )
232) data[emptyY + y][emptyX + x][c] = (byte)((((int)this.data[skipY + y][skipX + x][c] & 0xFF) * maxval + this.maxval / 2) / this.maxval);
233) for( c = channels - 1; c < this.channels; c++ )
234) val += (int)this.data[skipY + y][skipX + x][c] & 0xFF;
235) div = this.maxval * (this.channels - channels + 1);
236) data[emptyY + y][emptyX + x][channels - 1] = (byte)((val * maxval + div / 2) / div);
237) }
238) }
239) }
240)
241) this.height = height;
242) this.width = width;
243) this.channels = channels;
244) this.maxval = maxval;
245) this.data = data;
246) }
247)
|
Blimp v.0.3 (2004-11-12)
Christian Heimke authored 13 years ago
|
248) public void scale( int height, int width )
249) {
250) byte[][][] data;
251) double scaleHor, scaleVer, ox, oy, ox1, oy1, val;
252) int c, nx, ny, x, y, oxi, oyi, ox1i, oy1i;
253)
254) if( height < 1 ) height = 1;
255) if( height > 1024 ) height = 1024;
256) if( width < 1 ) width = 1;
257) if( width > 1024 ) width = 1024;
258)
259) if( height == this.height &&
260) width == this.width )
261) return;
262)
263) scaleHor = (double)width / (double)this.width;
264) scaleVer = (double)height / (double)this.height;
265)
266) //allocate new data array
267) data = new byte[height][width][channels];
268)
269) //scale every channel
270) for( c = 0; c < channels; c++ )
271) {
272) for( ny = 0; ny < height; ny++ )
273) {
274) for( nx = 0; nx < width; nx++ )
275) {
276) oy = (double)ny / scaleVer; //sub-pixel exact range in old picture
277) ox = (double)nx / scaleHor;
278) oy1 = (double)(ny + 1) / scaleVer - 0.000001;
279) ox1 = (double)(nx + 1) / scaleHor - 0.000001;
280) if( oy < 0 || ox < 0 || oy1 >= this.height || ox1 >= this.width) //out of old picture
281) data[ny][nx][c] = 0;
282) else
283) {
284) oyi = (int)oy;
285) oxi = (int)ox;
286) oy1i = (int)oy1;
287) ox1i = (int)ox1;
288) if( oyi == oy1i )
289) {
290) if( oxi == ox1i) //one source pixel
291) {
292) val = (double)((int)this.data[oyi][oxi][c] & 0xFF);
293) }
294) else //one line of source pixels
295) {
296) val = (double)((int)this.data[oyi][oxi][c] & 0xFF) * (1 - ox + oxi)
297) + (double)((int)this.data[oyi][ox1i][c] & 0xFF) * (ox1 - ox1i);
298) for( x = oxi + 1; x < ox1i; x++ )
299) val += (double)((int)this.data[oyi][x][c] & 0xFF);
300) val /= ox1 - ox;
301) }
302) }
303) else //one column of source pixels
304) {
305) if( oxi == ox1i )
306) {
307) val = (double)((int)this.data[oyi][oxi][c] & 0xFF) * (1 - oy + oyi)
308) + (double)((int)this.data[oy1i][oxi][c] & 0xFF) * (oy1 - oy1i);
309) for( y = oyi + 1; y < oy1i; y++ )
310) val += (double)((int)this.data[y][oxi][c] & 0xFF);
311) val /= oy1 - oy;
312) }
313) else //rectangle of source pixels
314) {
315) val = (double)((int)this.data[oyi][oxi][c] & 0xFF) * (1 - oy + oyi) * (1 - ox + oxi)
316) + (double)((int)this.data[oyi][ox1i][c] & 0xFF) * (1 - oy + oyi) * (ox1 - ox1i)
317) + (double)((int)this.data[oy1i][oxi][c] & 0xFF) * (oy1 - oy1i) * (1 - ox + oxi)
318) + (double)((int)this.data[oy1i][ox1i][c] & 0xFF) * (oy1 - oy1i) * (ox1 - ox1i);
319) for( y = oyi + 1; y < oy1i; y++ )
320) {
321) val += (double)((int)this.data[y][oxi][c] & 0xFF) * (1 - ox + oxi)
322) + (double)((int)this.data[y][ox1i][c] & 0xFF) * (ox1 - ox1i);
323) }
324) for( x = oxi + 1; x < ox1i; x++ )
325) {
326) val += (double)((int)this.data[oyi][x][c] & 0xFF) * (1 - oy + oyi)
327) + (double)((int)this.data[oy1i][x][c] & 0xFF) * (oy1 - oy1i);
328) }
329) for( y = oyi + 1; y < oy1i; y++ )
330) for( x = oxi + 1; x < ox1i; x++ )
331) val += (double)((int)this.data[y][x][c] & 0xFF);
332) val /= (oy1 - oy) * (ox1 - ox);
333) }
334) }
335) data[ny][nx][c] = (byte)(int)(val + 0.5);
336) }
337) } //for( nx ...
338) } //for( ny ...
339) } //for( c ...
340)
341) this.height = height;
342) this.width = width;
343) this.data = data;
344) }
345)
|
Blimp v.0.2 (2004-11-10)
Christian Heimke authored 13 years ago
|
346) public String toString( )
347) {
348) String str = "";
349) int h, w, c, val;
350) for( h = 0; h < height; h++ )
351) {
352) for( w = 0; w < width; w++ )
353) {
354) val = 0;
355) for( val = 0, c = 0; c < channels; c++ )
|
Blimp v.0.6 (2005-03-10)
Christian Heimke authored 13 years ago
|
356) val += ((int)data[h][w][c] & 0xFF);
|