Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libRaster / src / org / gvsig / raster / grid / GridTransparency.java @ 33331

History | View | Annotate | Download (8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.grid;
20

    
21
import org.gvsig.raster.datastruct.Transparency;
22
import org.gvsig.raster.datastruct.TransparencyRange;
23
import org.gvsig.tools.ToolsLocator;
24
import org.gvsig.tools.dynobject.DynClass;
25
import org.gvsig.tools.dynobject.DynStruct;
26
import org.gvsig.tools.persistence.PersistenceManager;
27
import org.gvsig.tools.persistence.PersistentState;
28
import org.gvsig.tools.persistence.exception.PersistenceException;
29

    
30
//TODO: FUNCIONALIDAD: Convertir la transparencia a String y viceversa para salvar proyecto
31
/**
32
 * <P>
33
 * Representa el estado de transparencia de un grid. 
34
 * </P>
35
 * <P>
36
 * El estado de transparencia de un raster puede verse modificado desde los siguientes sitios:
37
 * <UL>
38
 * <LI>Color con transparencia definido en los metadatos de la imagen. Caracteristica de PNG.</LI>
39
 * <LI>Una banda del raster definida como banda de transparencia. PNGs, IMGs o TIFFs 
40
 * pueden tener bandas de transparencia</LI>
41
 * <LI>Tablas de color con valores de transparencia. GIF y PNG pueden tener tablas 
42
 * que definan entradas de color con transparencia</LI>
43
 * <LI>Informaci?n de transparencia en la cabecera raster. Tipicamente valores NO_DATA suelen 
44
 * ser interpretados como transparentes en la visualizaci?n.</LI>
45
 * <LI>Modificaci?n hecha por el usuario. En la visualizaci?n un usuario puede necesitar
46
 * asignar valores o rangos de valores como transparentes.</LI>
47
 * </UL> 
48
 * </P>
49
 * <P>
50
 * Estas transparencias quedan representadas por cinco tipo b?sicos:
51
 * <UL>
52
 * <LI><b>Transparencia por rangos. </b>Esta se aplicar? antes que ninguna y siempre sobre los valores
53
 * base del raster.</LI>
54
 * <LI><b>Banda de transparencia en un raster. </b></LI>
55
 * <LI>M?scara de transparencia</LI>
56
 * <LI>Opacidad</LI>
57
 * <LI>Zona de recorte</LI>
58
 * </UL>
59
 * </P>
60
 * @author Nacho Brodin (nachobrodin@gmail.com)
61
 *
62
 */
63
public class GridTransparency extends Transparency {
64
        /**
65
         * Flag de activaci?n de la transparencia cuando se visualiza o exporta.
66
         */
67
        private boolean                 transparencyActive           = false;
68
                        
69
        /**
70
         * Constructor. Crea un objeto con las propiedades de la transparencia de un grid. 
71
         * Las variables conservan sus valores por defecto
72
         */
73
        public GridTransparency(){
74
                super();
75
                activeTransparency();
76
        };
77
        
78
        /**
79
         * Constructor. Crea un objeto con las propiedades de la transparencia de fichero
80
         * pasado como par?metro.
81
         * @param fileStatus Transparencia.
82
         */
83
        public GridTransparency(Transparency transp) {
84
                super(transp);
85
                activeTransparency();
86
        }
87
        
88
        /**
89
         * Comprueba si hay criterios para la aplicaci?n de transparencia y la activa si es
90
         * as? sino se desactiva. Los criterios son:
91
         * <P>
92
         * Que haya una mascara de transparencia.
93
         * </P><P>
94
         * Que exista un buffer de datos para la aplicaci?n de nodata
95
         * </P><P>
96
         * Que hayan reglas sobre la aplicaci?n de transparencia.
97
         * </P><P>
98
         * Que la opacidad sea distita de 255 (completamente opaco). 
99
         * </P>
100
         */
101
        public void activeTransparency() {
102
                if(        existAlphaBand() || isNoDataActive() ||
103
                        (transparencyRanges.size() > 0) ||
104
                        (opacity != 0xff))
105
                        transparencyActive = true;
106
                else
107
                        transparencyActive = false;
108
        }
109
        
110
        /**
111
         * Aplica las reglas de transparencia a un pixel RGB y devuelve el valor de ese
112
         * mismo pixel con la transparencia aplicada. Primero procesar? los rangos. Si
113
         * el pixel est? en alguno directamente lo pone transparente y lo devuelve, sino
114
         * comprueba si existe banda de transparencia y si es as? la aplica.
115
         * @param rgb
116
         * @param line
117
         * @param col
118
         * @return
119
         */
120
        public int processRGB(int r, int g, int b, int line, int col) {
121
                // Si el valor es noData se pone totalmente transparente y ya no se tiene en
122
                // cuenta nada m?s.
123
                if (originalData != null && isNoDataActive()) {
124
                        if (isNoData(line, col))
125
                                // El alpha no se pone para dejarlo a 0, totalmente transparente
126
                                return (r << 16 | g << 8 | b);
127
                }
128

    
129
                /**
130
                 * Para sacar el valor del nuevo alpha, lo que hacemos es convertir a
131
                 * porcentajes todos los alphas posibles (en porcentajes) y multiplicarlos
132
                 * entre si. Con esto conseguimos un nuevo porcentaje de alpha entre 0 y 1.
133
                 * Una vez hecho esto se multiplica por 255 para tenerlo dentro del rango
134
                 * deseado. Como queremos evitar operaciones de m?s, podemos quitar una
135
                 * division de 255 y as? nos ahorramos luego multiplicarlo por 255 otra vez.
136
                 */
137

    
138
                // Quitada la division para optimizar
139
                //double a = opacity / 255D;
140
                double a = opacity;
141

    
142
                int alphaRange = processRange(r, g, b);
143
                if (alphaRange != 255)
144
                        a *= (alphaRange / 255D);
145

    
146
                if (existAlphaBand() && getAlphaBand() != null)
147
                        a *= (getAlphaBand().getElemByte(line, col, 0) & 0xff) / 255D;
148

    
149
                // Quitada la multiplicacion para optimizar
150
                // a = (int)(a * 255D);
151

    
152
                return ((int) a << 24) | r << 16 | g << 8 | b;
153
        }
154
        
155
        /**
156
         * Aplica la transparecia por rangos al pixel pasado por par?metro. El valor
157
         * en la posici?n cero es el alpha por lo tanto ser? esta posici?n la que se
158
         * modificar?.
159
         * @param r
160
         * @param g
161
         * @param b
162
         * @return Un valor de 0 a 255. Donde 255 es totalmente opaco
163
         */
164
        private int processRange(int r, int g, int b) {
165
                for (int i = 0; i < transparencyRanges.size(); i++) {
166
                        TransparencyRange tr = ((TransparencyRange) transparencyRanges.get(i));
167
                        if (tr == null) continue;
168
                        if (tr.isAnd()) {
169
                                if (tr.getRed() == null ||
170
                                                tr.getGreen() == null ||
171
                                                tr.getBlue() == null ||
172
                                                r < tr.getRed()[0]   || r > tr.getRed()[1] ||
173
                                                g < tr.getGreen()[0] || g > tr.getGreen()[1] ||
174
                                                b < tr.getBlue()[0]  || b > tr.getBlue()[1])
175
                                        continue;
176

    
177
                                return tr.getAlpha();
178
                        } else {
179
                                if (tr.getRed() != null) {
180
                                        if (r >= tr.getRed()[0] && r <= tr.getRed()[1]) {
181
                                                return tr.getAlpha();
182
                                        }
183
                                }
184
                                if (tr.getGreen() != null) {
185
                                        if (g >= tr.getGreen()[0] && g <= tr.getGreen()[1]) {
186
                                                return tr.getAlpha();
187
                                        }
188
                                }
189
                                if (tr.getBlue() != null) {
190
                                        if (b >= tr.getBlue()[0] && b <= tr.getBlue()[1]) {
191
                                                return tr.getAlpha();
192
                                        }
193
                                }
194
                        }
195
                }
196
                return 255;
197
        }
198
                
199
        /**
200
         * Obtiene el flag de transparencia activa o desactivada.
201
         * @return true la transparencia est? activa y false desactiva
202
         */
203
        public boolean isTransparencyActive() {
204
                return transparencyActive;
205
        }
206
        
207
        /**
208
         * Asigna el flag de transparencia activa o desactivada.
209
         * @param transparencyActive true activa la transparencia false la desactiva
210
         */
211
        public void setTransparencyActive(boolean transparencyActive) {
212
                this.transparencyActive = transparencyActive;
213
        }
214
        
215
        public static void registerPersistent() {
216
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
217
                DynStruct definition = manager.addDefinition(
218
                                GridTransparency.class,
219
                                "GridTransparency_Persistent",
220
                                "GridTransparency Persistent definition",
221
                                null, 
222
                                null
223
                );
224
                definition.extend(
225
                                (DynClass)ToolsLocator.getPersistenceManager()
226
                                        .getDefinition(Transparency.class)
227
                );
228
                definition.addDynFieldBoolean("transparencyActive");
229
        }
230
                        
231
        @Override
232
        public void loadFromState(PersistentState state)
233
                        throws PersistenceException {
234
                super.loadFromState(state);
235
                this.transparencyActive = state.getBoolean("transparencyActive");
236
        }
237
        
238
        @Override
239
        public void saveToState(PersistentState state) throws PersistenceException {
240
                super.saveToState(state);
241
                state.set("transparencyActive",transparencyActive);
242
        }
243
}