Statistics
| Revision:

svn-gvsig-desktop / trunk / docs / Cresques / Cresques.html @ 2248

History | View | Annotate | Download (21.9 KB)

1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2
<HTML>
3
<HEAD>
4
        <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-15">
5
        <TITLE>FMap</TITLE>
6
        <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.0  (Linux)">
7
        <META NAME="CREATED" CONTENT="20050622;16400400">
8
        <META NAME="CHANGED" CONTENT="20050622;18200900">
9
        <STYLE>
10
        <!--
11
                @page { size: 21cm 29.7cm; margin-left: 2cm; margin-right: 1.06cm; margin-top: 1.06cm; margin-bottom: 1.06cm }
12
                TD P { color: #676767; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 9pt; font-style: normal; text-align: justify }
13
                P { font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 9pt; text-align: justify }
14
                PRE { margin-left: 5cm }
15
                A:link { color: #e86d26; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 9pt; font-style: normal }
16
        -->
17
        </STYLE>
18
</HEAD>
19
<BODY LANG="es-ES" LINK="#e86d26" DIR="LTR">
20
<TABLE WIDTH=600 BORDER=0 CELLPADDING=2 CELLSPACING=0 STYLE="page-break-before: always">
21
        <COL WIDTH=30>
22
        <COL WIDTH=562>
23
        <TR>
24
                <TD WIDTH=30>
25
                        <P>&nbsp;</P>
26
                </TD>
27
                <TD WIDTH=562 BGCOLOR="#e86d26">
28
                        <P><A HREF="#Introduccion"><SPAN STYLE="background: #e86d26"><B><FONT COLOR="#ffffff">1.
29
                        Introducci&oacute;n</FONT></B></SPAN></A></P>
30
                </TD>
31
        </TR>
32
        <TR>
33
                <TD WIDTH=30>
34
                        <P>&nbsp;</P>
35
                </TD>
36
                <TD WIDTH=562 BGCOLOR="#e86d26">
37
                        <P><A HREF="#Filtros"><SPAN STYLE="background: #e86d26"><B><FONT COLOR="#ffffff">2.
38
                        Filtros</FONT></B></SPAN></A></P>
39
                </TD>
40
        </TR>
41
        <TR>
42
                <TD WIDTH=30>
43
                        <P>&nbsp;</P>
44
                </TD>
45
                <TD WIDTH=562>
46
                        <P>&nbsp;&nbsp;&nbsp; <A HREF="#NewFiltro">2.1 Creaci&oacute;n de
47
                        un nuevo filtro</A></P>
48
                </TD>
49
        </TR>
50
        <TR>
51
                <TD WIDTH=30>
52
                        <P><BR>
53
                        </P>
54
                </TD>
55
                <TD WIDTH=562>
56
                        <P>&nbsp;&nbsp;&nbsp; <A HREF="#GestionFiltro">2.2 Gesti&oacute;n
57
                        de un nuevo filtro</A></P>
58
                </TD>
59
        </TR>
60
</TABLE>
61
<P><A NAME="Introduccion"></A><A NAME="Filtros"></A><A NAME="NewFiltro"></A>
62
<STRONG><FONT SIZE=5>1.Introducci&oacute;n</FONT></STRONG><BR><BR><STRONG><FONT SIZE=5>2.
63
Filtros</FONT></STRONG><BR><BR><STRONG><FONT SIZE=4>2.1 Creaci&oacute;n
64
de un nuevo filtro</FONT></STRONG></P>
65
<P STYLE="margin-left: 0.02cm">&nbsp;&nbsp;&nbsp; Crear una nueva
66
clase abstracta que heredar&aacute; de RasterFilter y que tendr&aacute;
67
como nombre el nombre del filtro (en ingl&eacute;s a poder ser)
68
seguido de Filter. Usaremos como ejemplo la generaci&oacute;n del
69
filtro de transparencia. En este caso, esta clase abstracta debe
70
llamarse TransparencyFilter. 
71
</P>
72
<P>&nbsp;&nbsp;&nbsp; Crear una clase que hereda de esta clase que
73
hemos creado para cada tipo de dato b&aacute;sico que se da soporte.
74
En nuestro caso dos clases heredan de TransparencyFilter y son
75
TransparencyImageFilter y TransparencyShortFilter. Notese que la
76
nomenclatura hace referencia al tipo de dato que maneja. La primera
77
funciona para objetos Image de java y la segunda para im&aacute;genes
78
de 16 bits.Estas &uacute;ltimas est&aacute;n representadas por una
79
clase llamada RasterBuf. Si fuera necesario deber&iacute;a hacerse
80
para Float, Double, ... 
81
</P>
82
<P>&nbsp;&nbsp;&nbsp; El constructor de los filtros es recomendable
83
que est&eacute; vacio.</P>
84
<P>&nbsp;&nbsp;&nbsp; En la clase base del filtro que estamos creando
85
(TransparencyFilter) deben ponerse las variables de instancia que
86
contengan los par&aacute;metros necesarios para el filtro. En este
87
caso tendriamos 3 vectores bidimensionales que contendran los
88
intervalos de valores a poner como transparentes y cuatro enteros que
89
representan el alpha y el color de transparencia en caso de querer
90
proporcionar alguno. Por defecto ser&aacute; blanco, es decir
91
totalmente transparente y sin ninguna tonalidad.</P>
92
<P>&nbsp;&nbsp;&nbsp; Aqu&iacute; deben ponerse tambi&eacute;n todas
93
las funcionalidades comunes a todos los tipos de filtro de
94
transparencia. Como TransparencyFilter hereda de RasterFilter que es
95
abstracta y tiene m&eacute;todos abstractos obligar&aacute; a
96
implementar estos. Si es necesario que estos m&eacute;todos
97
abstractos tengan c&oacute;digo podemos implementarlos aqu&iacute;
98
sino podr&aacute; hacerse en las clases hijas que contienen la
99
especificaci&oacute;n para el filtro de transparencia sobre cada tipo
100
de dato concreto. Los m&eacute;todos abstractos que es preciso
101
implementar son:</P>
102
<UL>
103
        <LI><P><B>abstract public void pre();</B> .</P>
104
</UL>
105
<P>&nbsp;&nbsp;&nbsp; Aqu&iacute; pondremos las operaciones que hay
106
que realizar antes de ejecutar el filtro que estamos creando. En
107
nuestro caso est&aacute; implementado en la clase base del filtro y
108
en las hijas . En la clase base tiene c&oacute;digo com&uacute;n para
109
los filtros de transparencia de cualquier tipo de datos.</P>
110
<PRE>        public void pre(){
111
                this.rangesR = (int[][])params.get(&quot;red&quot;);
112
                this.rangesG = (int[][])params.get(&quot;green&quot;);
113
                this.rangesB = (int[][])params.get(&quot;blue&quot;);
114
                this.alpha = ((Integer)params.get(&quot;alpha&quot;)).intValue();
115
                this.transparencyColorRed = ((Integer)params.get(&quot;transparencyRed&quot;)).intValue();
116
                this.transparencyColorGreen = ((Integer)params.get(&quot;transparencyGreen&quot;)).intValue();
117
                this.transparencyColorBlue = ((Integer)params.get(&quot;transparencyBlue&quot;)).intValue();
118
        }</PRE><P>
119
&nbsp;&nbsp;&nbsp; En las clases hijas se pone la implementaci&oacute;n
120
concreta para ese tipo de dato. En el caso de la transparencia sobre
121
un Image obtenemos el par&aacute;metro que contiene la Image y
122
asignamos los valore de altura y anchura de raster a partir de este
123
Image. Antes de finalizar llama al pre() de TransparencyFilter.</P>
124
<PRE>        public void pre(){
125
                this.image = (Image)params.get(&quot;raster&quot;);
126
                height = image.getHeight(null);
127
                width = image.getWidth(null);
128
                super.pre();
129
        }</PRE>
130
<UL>
131
        <LI><P><B>abstract public void post();</B></P>
132
</UL>
133
<P>&nbsp;&nbsp;&nbsp; Aqu&iacute; se ponen las operaciones a realizar
134
despu&eacute;s de ejecutar el filtro. En el caso que estamos viendo
135
no es necesario hacer nada por lo que estar&aacute; vacio. Podria ser
136
necesario alguna operaci&oacute;n como por ejemplo cargar el
137
resultado de la operaci&oacute;n en alguna variable de salida o algo
138
as&iacute;.</P>
139
<UL>
140
        <LI><P><B>abstract public void process(int x, int y);</B></P>
141
</UL>
142
<P>&nbsp;&nbsp;&nbsp; Este m&eacute;todo es el encargado de procesar
143
el filtro para un pixel de la imagen. La clase abstracta RasterFilter
144
de la cual heredan todos los filtros tiene el metodo execute() que
145
har&aacute; lo siguiente:</P>
146
<PRE>                pre();
147
                     for (int y=0; y&lt;height; y=y+incY)
148
                        for (int x=0; x&lt;width; x=x+incX) {
149
                                process(x, y);
150
                        }
151
                post();</PRE><P>
152
&nbsp;&nbsp;&nbsp; Por esto debemos tener en process el c&oacute;digo
153
que ejecuta el filtro. Esto siempre suele rellenarse en las clases
154
que representan a un filtro de un tipo de dato concreto. Para nuestro
155
ejemplo en TransparencyImageFilter el process tendr&aacute; el
156
siguiente c&oacute;digo:</P>
157
<PRE>        public void process(int x, int y) {
158
                int pt = ((BufferedImage) image).getRGB(x,y);
159
                int []px4 = {(pt &amp; 0xff000000) &gt;&gt; 24,(pt &amp; 0xff0000) &gt;&gt; 16, (pt &amp; 0x00ff00) &gt;&gt; 8, (pt &amp;                                 0x0000ff)};
160
                if(rangesR!=null)
161
                        processRange(rangesR, 1, px4);
162
                if(rangesG!=null)
163
                        processRange(rangesG, 2, px4);
164
                if(rangesB!=null)
165
                        processRange(rangesB, 3, px4);
166
                ((BufferedImage) image).setRGB(x,y, (
167
                        (px4[0] &lt;&lt; 24) &amp; 0xff000000 | (px4[1] &lt;&lt; 16) &amp; 0x00ff0000 |
168
                        (px4[2] &lt;&lt; 8)  &amp; 0x0000ff00 | (px4[3] &amp; 0x0000ff) ));
169
        }</PRE><P>
170
<BR><BR>
171
</P>
172
<P>&nbsp;&nbsp;&nbsp; Esta funci&oacute;n obtendr&aacute; el pixel
173
del buffer lo procesar&aacute; y salvar&aacute; el resultado sobre el
174
mismo buffer.</P>
175
<UL>
176
        <LI><P><B>abstract public void processLine(int y);</B></P>
177
</UL>
178
<P>&nbsp;&nbsp;&nbsp; Esta funci&oacute;n realizar&aacute; el mismo
179
proceso que process(int x, int y) pero aplicada directamente a una
180
l&iacute;nea del buffer.</P>
181
<UL>
182
        <LI><P><B>abstract public int getInRasterDataType();</B></P>
183
</UL>
184
<P>&nbsp;&nbsp;&nbsp; Devuelve el tipo de dato del buffer de entrada.
185
La clase RasterBuf tiene constantes que tiene todos los tipos de
186
datos posibles por lo que puede realizarse algo as&iacute;:</P>
187
<PRE>        public int getInRasterDataType(){
188
                return RasterBuf.TYPE_IMAGE;
189
        <I>}</I>       </PRE>
190
<UL>
191
        <LI><P><B>abstract public int getOutRasterDataType();</B></P>
192
</UL>
193
<P>&nbsp;&nbsp;&nbsp; Devuelve el tipo de dato del buffer de salida.
194
La clase RasterBuf tiene constantes que tiene todos los tipos de
195
datos posibles por lo que puede realizarse algo as&iacute;: 
196
</P>
197
<PRE>        <I>public int getOutRasterDataType(){</I>
198
                return RasterBuf.TYPE_IMAGE;
199
        }</PRE>
200
<UL>
201
        <LI><P><B>abstract public Object getResult(String name);</B></P>
202
</UL>
203
<P>&nbsp;&nbsp;&nbsp; Obtiene el resultado del filtro en un Object.
204
Para esto se la pasa un par&aacute;metro con la clave del resultado y
205
nos devolver&aacute; el Object correspondiente. Esto es necesario
206
porque un mismo filtro puede tener varias salidas, por ejemplo puede
207
tener un raster con el resultado de aplicar el filtro y una clase con
208
algunas estadisticas calculadas en el proceso. En este caso el filtro
209
de transparencia solo devuelve un raster de salida por lo que se har&aacute;
210
una funci&oacute;n por tipo de dato tal que:</P>
211
<PRE>        public Object getResult(String name){
212
                if(name.equals(&quot;raster&quot;))
213
                        return (Object)this.image;
214
                else 
215
                        return null;
216
        <FONT SIZE=2 STYLE="font-size: 9pt">}</FONT></PRE><P>
217
<A NAME="GestionFiltro"></A>&nbsp;&nbsp;&nbsp; Esta es la que se har&aacute;
218
para TransparencyImageFilter ya que devuelve un tipo Image.</P>
219
<P><BR>&nbsp;<BR><STRONG><FONT SIZE=4>2.2 Gesti&oacute;n de un nuevo
220
filtro</FONT></STRONG></P>
221
<P>&nbsp;&nbsp;&nbsp; Para el almacenaje de filtros seleccionados hay
222
una clase llamada RasterFilterStack que contiene la pila de filtros y
223
que es generica para cualquier tipo de filtro realizado, es decir, en
224
condiciones normales, en la creaci&oacute;n de un nuevo filtro esta
225
clase no debe tocarse. Sin embargo si debe a&ntilde;adirse la gesti&oacute;n
226
del nuevo filtro con filterStackManager . Para a&ntilde;adir este
227
nuevo filtro deber&aacute; crearse una nueva clase que heredar&aacute;
228
de RasterFilterStackManager. RasterFilter esla encargada de a&ntilde;adir
229
filtros a la pila ya que ella es la que sabr&aacute; el orden en el
230
que deben ir estos . Un orden de la pila incorrecto da un resultado
231
de aplicaciones de filtros indeseado. Con esto deducimos que la pila
232
es tratada como tal para la ejecuci&oacute;n de filtros pero que
233
estos deben estar de antemano ordenados correctamente por lo que no
234
es una pila en el sentido estricto.</P>
235
<P>&nbsp;&nbsp;&nbsp; Este nuevo gestor de filtros deber&aacute;
236
implementar la interfaz StackManager de forma que la definici&oacute;n
237
de nuestra nueva clase ser&iacute;a m&aacute;s o menos asi:</P>
238
<PRE>public class PruebaStackManager extends RasterFilterStackManager implements StackManager{
239
...
240
}</PRE><P>
241
&nbsp;&nbsp;&nbsp; Para el nuevo filtro debe a&ntilde;adirse en esta
242
nueva clase una constante que represente el tipo del nuevo filtro. Lo
243
m&aacute;s l&oacute;gico es darle un n&uacute;mero de orden
244
consecutivo a las que hay pero podr&iacute;a asignarse otro en caso
245
de haber una causa justificada. Las actualmente asignadas en la
246
RasterFilterStackManager son 
247
</P>
248
<PRE>        <I>transparency = 0;</I>
249
        enhanced=1;
250
        computeminmax=2;
251
        tail=3;</PRE><P>
252
&nbsp;&nbsp;&nbsp; El vector order de RasterFilterStackManager
253
contiene la forma de ordenaci&oacute;n de los filtros de la pila.
254
Este orden es importante, por ejemplo la transparencia debe aplicarse
255
despues del realce de la imagen ya que esta se aplica a rangos de
256
colores y antes o despu&eacute;s del realce los rangos de colores
257
difieren por lo que la transparencia debe aplicarse sobre la imagen
258
realzada y no al rev&eacute;s. Para asignar este nuevo order
259
deberemos indicarlo en el constructor de esta clase que hemos creado.</P>
260
<PRE>        public PruebaStackManager(RasterFilterStack filterStack){
261
                super(filterStack);
262
                addTypeFilter(&quot;prueba&quot;, PruebaStackManager.prueba, 2);
263
        }</PRE><P>
264
<BR><BR>
265
</P>
266
<P>&nbsp;&nbsp;&nbsp; Habr&aacute; que elegir una posici&oacute;n
267
para el nuevo filtro creado para que produzca el resultado deseado.
268
La funci&oacute;n addTypeFilter tendr&aacute; como par&aacute;metros
269
en nombre del filtro, constante asignada y posici&oacute;n para la
270
ordenaci&oacute;n. Si introducimos el nuevo filtro en la posici&oacute;n
271
3 la ordenaci&oacute;n inicial:</P>
272
<PRE STYLE="margin-bottom: 0.5cm">computeminmax, tail, enhanced, transparency </PRE><P>
273
<BR><BR>
274
</P>
275
<P>quedar&aacute; 
276
</P>
277
<PRE STYLE="margin-bottom: 0.5cm">computeminmax, tail, prueba, enhanced, transparency </PRE><P>
278
<BR><BR>
279
</P>
280
<P>ya que la posici&oacute;n en el vector de ordenaci&oacute;n tiene
281
en cuenta la posici&oacute;n 0.</P>
282
<P>&nbsp;&nbsp;&nbsp; En RasterFilterStackManager tambi&eacute;n
283
existe una funci&oacute;n llamada getType que devuelve el tipo de
284
filtro que contiene un RasterFilter. Deberemos a&ntilde;adir el
285
nuestro para una correcta gesti&oacute;n. Para ello sobrescribiremos
286
el m&eacute;todo getType de esta forma:</P>
287
<PRE>        <SPAN STYLE="font-style: normal">public int getType(RasterFilter rasterFilter){</SPAN>
288
                if(rasterFilter instanceof &lt;&lt;NuestoFiltro&gt;&gt;)
289
                        return PruebaStackManager.&lt;&lt;Nuestra constante&gt;&gt;;
290
                                        
291
                return super.getType(rasterFilter);
292
        }</PRE><P>
293
<BR><BR>
294
</P>
295
<P>sustituyendo &lt;&lt;NuestroFiltro&gt;&gt; por el nombre de la
296
clase abstracta base del filtro que hemos construido y &lt;&lt;Nuestra
297
constante&gt;&gt; por la constante que representa nuestro filtro.</P>
298
<P>&nbsp;&nbsp;&nbsp; Dentro de nuestra clase habr&aacute; que
299
definir una funci&oacute;n para a&ntilde;adir el nuevo filtro. Esta
300
funci&oacute;n debe tener como argumentos los par&aacute;metros
301
necesarios para el nuevo filtro. En el caso de un filtro de
302
transparencia podrian ser los intervalos para RGB y el color de
303
transparencia.</P>
304
<P>&nbsp;&nbsp;&nbsp; En esta funci&oacute;n hay que hacer algunas
305
acciones obligatorias y otras opcionales. Podemos verlas sobre un
306
ejemplo:</P>
307
<P>&nbsp;&nbsp;&nbsp; Cabecera de la funci&oacute;n ya comentada:</P>
308
<P><BR><BR>
309
</P>
310
<PRE>                <SPAN STYLE="font-style: normal">public void addTransparencyFilter(      int[][] red,</SPAN>
311
                                                        int[][] green,
312
                                                        int[][] blue,
313
                                                        int alpha,
314
                                                        int transparencyRed,
315
                                                        int transparencyGreen,
316
                                                        int transparencyBlue){
317
                </PRE><P>
318
&nbsp;&nbsp;&nbsp; Es necesario crear un RasterFilter de un tipo u
319
otro dependiendo del tipo de dato que nos diga la pila que necesita.
320
El m&eacute;todo
321
filterStack.getDataTypeInFilter(RasterFilterStackManager.transparency)
322
devuelve el tipo de dato que necesitamos si el filtro que vamos a
323
meter es de transparencia. Esta funci&oacute;n de la pila calcular&aacute;
324
en que posici&oacute;n debe ir el filtro y que tipo de dato devuelve
325
el que tendr&aacute; por encima, por lo tanto sabremos de que tipo es
326
el filtro que debemos crear. Podemos hacer la selecci&oacute;n con un
327
switch de esta forma:</P>
328
<PRE>                <SPAN STYLE="font-style: normal">RasterFilter filtro = null;</SPAN>
329
                switch(filterStack.getDataTypeInFilter(((Integer)typeFilters.get(&quot;transparency&quot;)).intValue())){
330
                        case RasterBuf.TYPE_IMAGE:filtro = new TransparencyImageFilter();break;
331
                        case RasterBuf.TYPE_SHORT:
332
                        case RasterBuf.TYPE_USHORT:
333
                        case RasterBuf.TYPE_INT:filtro = new TransparencyShortFilter();break;
334
                }</PRE><P>
335
<BR><BR>
336
</P>
337
<P>&nbsp;&nbsp;&nbsp; Si tiene par&aacute;metros deberemos a&ntilde;adirlos
338
al filtro creado con addParam. Cada par&aacute;metro debe ser a&ntilde;adido
339
con una clave. Esta debe coincidir con la que definimos para su
340
recuperaci&oacute;n en el m&eacute;todo pre() del filtro.</P>
341
<PRE>                <SPAN STYLE="font-style: normal">if(red != null)filtro.addParam(&quot;red&quot;, red);</SPAN>
342
                if(green != null)filtro.addParam(&quot;green&quot;, green);
343
                if(blue != null)filtro.addParam(&quot;blue&quot;, blue);
344
                filtro.addParam(&quot;alpha&quot;, new Integer(alpha));
345
                filtro.addParam(&quot;transparencyRed&quot;, new Integer(transparencyRed));
346
                filtro.addParam(&quot;transparencyGreen&quot;,  new Integer(transparencyGreen));
347
                filtro.addParam(&quot;transparencyBlue&quot;,  new Integer(transparencyBlue));</PRE><P>
348
&nbsp;&nbsp;&nbsp; En este momento podriamos a&ntilde;adir el filtro
349
a la pila con addFilter si no necesitara ninguna restricci&oacute;n.
350
En este caso tenemos que a&ntilde;adir c&oacute;digo para comprobar
351
que si hay filtros equivalentes no ser&aacute; necesario a&ntilde;adir
352
el nuevo o si hay varios filtros de transparencia que est&aacute;n
353
contenidos en el nuevo tendremos que eliminar estos y a&ntilde;adir
354
el nuevo.</P>
355
<PRE>                //Elimina los filtros que son equivalentes a este
356

    
357
                <SPAN STYLE="font-style: normal">for(int i=0;i&lt;filterStack.lenght();i++){</SPAN>
358
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
359
                                filterStack.get(i) instanceof TransparencyShortFilter){
360
                                 
361
                                //Si este filtro es equivalente a uno de la pila se elimina este
362
                                if(((TransparencyFilter)filtro).isEquivalent((TransparencyFilter)filterStack.get(i)))
363
                                        filterStack.removeFilter(filterStack.get(i));   
364
                                
365
                        }       
366
                }
367
                //A&ntilde;ade el filtro si no hay uno equivalente 
368
                
369
                <SPAN STYLE="font-style: normal">boolean equivalentFilter = false;</SPAN>
370
                for(int i=0;i&lt;filterStack.lenght();i++){
371
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
372
                                filterStack.get(i) instanceof TransparencyShortFilter){
373
                                
374
                                //Si no existe en la pila un filtro equivalente se a&ntilde;ade
375
                                if(((TransparencyFilter)filterStack.get(i)).isEquivalent((TransparencyFilter)filtro)){
376
                                        equivalentFilter = true;
377
                                        break;
378
                                }
379
                        }       
380
                }
381
                if(!equivalentFilter)
382
                        filterStack.addFilter(RasterFilterStackManager.transparency, filtro);
383
        }</PRE><P>
384
&nbsp;&nbsp;&nbsp; Teniendo la nueva funci&oacute;n para a&ntilde;adir
385
filtro ya podremos a&ntilde;adirlo desde un dialogo creando un
386
RasterFilterStackManager o usando uno ya creado y leyendo los
387
par&aacute;metros del filtro desde el cuadro (tambi&eacute;n podemos
388
ponerlos fijos si nos interesa). En nuestro caso:</P>
389
<PRE>stackManager.addTransparencyFilter( contentPane.getRangeRed(),  //Par&aacute;metros leidos desde el dialogo                                            contentPane.getRangeGreen(),
390
contentPane.getRangeBlue(),     
391
0x10,                                                                 //Par&aacute;metros a valor fijo                         
392
0xff,
393
0xff,
394
0xff);</PRE><P>
395
&nbsp;&nbsp;&nbsp; Para que sea posible salvar el estado de un raster
396
cuando se salva un proyecto y se le hayan aplicado filtros es
397
necesario codificar esta posibilidad para ello deberemos crear dos
398
m&eacute;todos obligados por el interfaz en nuestro Manager. Estos
399
son:</P>
400
<PRE>        public ArrayList getStringsFromStack(RasterFilter rf);  y 
401
        public void createStackFromStrings(ArrayList f, Integer pos);</PRE><P>
402
&nbsp;&nbsp;&nbsp; En el primero es para a&ntilde;adir las cadenas al
403
XML que salva el proyecto y habr&aacute; que comprobar si primero si
404
el RasterFilter pasado es instancia de este filtro que estamos
405
implementando y si lo es a&ntilde;adir las cadenas adecuadas de esta
406
forma:</P>
407
<PRE>        public ArrayList getStringsFromStack(RasterFilter rf){
408
                if(rf instanceof PruebaFilter){
409
                        filterList.add(&quot;filter.prueba.active=true&quot;);
410
                }
411
        }</PRE><P>
412
&nbsp;&nbsp;&nbsp; El segundo es para recuperar el estado de un
413
proyecto. Para ello lo primero que deberemos hacer es recuperar del
414
array el elemento analizado, comprobar que contiene la cadena que
415
representa nuestro filtro y si es as&iacute; eliminar esa entrada del
416
vector ya que ya ha sido analizada y a&ntilde;adir las acciones que
417
conllevan la adici&oacute;n de nuestro filtro. En este caso un simple
418
addPruebaFilter a&ntilde;adir&aacute; el filtro creado cuando se
419
habra un proyecto con la cadena filter.prueba.active=true.</P>
420
<PRE>        public void createStackFromStrings(ArrayList f, Integer pos){
421
                String fil = (String)f.get(pos);
422
                if(fil.startsWith(&quot;filter.prueba.active&quot;) &amp;&amp; getValue(fil).equals(&quot;true&quot;)){
423
                        filters.remove(pos.intValue());
424
                        this.addPruebaFilter();
425
                        pos = -1;
426
                }
427
        }</PRE>
428
</BODY>
429
</HTML>