Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / grid / GridTransparency.java @ 20871

History | View | Annotate | Download (6.87 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

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

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

    
132
                // Quitada la division para optimizar
133
                //double a = opacity / 255D;
134
                double a = opacity;
135

    
136
                int alphaRange = processRange(r, g, b);
137
                if (alphaRange != 255)
138
                        a *= (alphaRange / 255D);
139

    
140
                if (existAlphaBand() && getAlphaBand() != null)
141
                        a *= (getAlphaBand().getElemByte(line, col, 0) & 0xff) / 255D;
142

    
143
                // Quitada la multiplicacion para optimizar
144
                // a = (int)(a * 255D);
145

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

    
171
                                return tr.getAlpha();
172
                        } else {
173
                                if (tr.getRed() != null) {
174
                                        if (r >= tr.getRed()[0] && r <= tr.getRed()[1]) {
175
                                                return tr.getAlpha();
176
                                        }
177
                                }
178
                                if (tr.getGreen() != null) {
179
                                        if (g >= tr.getGreen()[0] && g <= tr.getGreen()[1]) {
180
                                                return tr.getAlpha();
181
                                        }
182
                                }
183
                                if (tr.getBlue() != null) {
184
                                        if (b >= tr.getBlue()[0] && b <= tr.getBlue()[1]) {
185
                                                return tr.getAlpha();
186
                                        }
187
                                }
188
                        }
189
                }
190
                return 255;
191
        }
192
                
193
        /**
194
         * Obtiene el flag de transparencia activa o desactivada.
195
         * @return true la transparencia est? activa y false desactiva
196
         */
197
        public boolean isTransparencyActive() {
198
                return transparencyActive;
199
        }
200
        
201
        /**
202
         * Asigna el flag de transparencia activa o desactivada.
203
         * @param transparencyActive true activa la transparencia false la desactiva
204
         */
205
        public void setTransparencyActive(boolean transparencyActive) {
206
                this.transparencyActive = transparencyActive;
207
        }
208
                        
209
}