Revision 184 trunk/libraries/libCq CMS for java.old/src/org/cresques/io/EcwFile.java
EcwFile.java | ||
---|---|---|
12 | 12 |
import com.ermapper.ecw.JNCSFileNotOpenException; |
13 | 13 |
import com.ermapper.ecw.JNCSProgressiveUpdate; |
14 | 14 |
import com.ermapper.util.JNCSDatasetPoint; |
15 |
import com.ermapper.util.JNCSWorldPoint; |
|
15 | 16 |
|
16 | 17 |
import org.cresques.cts.ICoordTrans; |
17 | 18 |
import org.cresques.cts.IProjection; |
18 | 19 |
import org.cresques.px.*; |
19 | 20 |
|
20 |
/** |
|
21 |
* Filtro para raster. |
|
22 |
* Permite eliminar la franja inutil alrededor de un raster girado o de |
|
23 |
* un mosaico de borde irregular. |
|
24 |
* |
|
25 |
* Funciona bien solo con raster en tonos de gris, porque se basa que |
|
26 |
* el valor del pixel no supere un determinado valor 'umbral' que se |
|
27 |
* le pasa al constructor. |
|
28 |
* |
|
29 |
* @author "Luis W. Sevilla" <sevilla_lui@gva.es> |
|
30 |
*/ |
|
31 | 21 |
|
32 |
class PixelFilter { |
|
33 |
boolean debug = false; |
|
34 |
int transparente = 0x10ffff00; |
|
35 |
int orColor = 0xff000000; |
|
36 |
int umbral = 0xf0f0f0; |
|
37 |
private int alpha = 0xff; |
|
38 |
|
|
39 |
/** |
|
40 |
* Constructor para el Oleico |
|
41 |
*/ |
|
42 |
|
|
43 |
public PixelFilter(int alpha) { |
|
44 |
transparente = 0x10ffff00; |
|
45 |
setAlpha(alpha); |
|
46 |
//orColor = 0xff000000 | (alpha * 0x1000000); |
|
47 |
umbral = 0xf0f0f0; |
|
48 |
} |
|
49 |
|
|
50 |
/** |
|
51 |
* Constructor. |
|
52 |
* |
|
53 |
* @param trans Color que sustituye a los pixeles filtrados |
|
54 |
* @param or M?scara que se aplica a los pixeles restantes |
|
55 |
* @param pxMax Umbral que determina los pixeles. |
|
56 |
*/ |
|
57 |
|
|
58 |
public PixelFilter(int trans, int or, int pxMax) { |
|
59 |
transparente = trans; |
|
60 |
setAlpha(orColor / 0x1000000); |
|
61 |
orColor = or; |
|
62 |
umbral = pxMax; |
|
63 |
} |
|
64 |
|
|
65 |
public void setAlpha(int alpha) { |
|
66 |
this.alpha = alpha; |
|
67 |
orColor = alpha * 0x1000000; |
|
68 |
} |
|
69 |
public int getAlpha() { return alpha; } |
|
70 |
|
|
71 |
/** |
|
72 |
* Filtra una l?nea de pixeles. |
|
73 |
* |
|
74 |
* @param pRGBArray |
|
75 |
*/ |
|
76 |
|
|
77 |
public void filterLine(int [] pRGBArray) { |
|
78 |
for (int i=0; i<pRGBArray.length; i++) { |
|
79 |
if (debug) |
|
80 |
System.out.print(""+i+":"+Integer.toHexString(pRGBArray[i])+","); |
|
81 |
if (pRGBArray[i] >= umbral) |
|
82 |
pRGBArray[i] = transparente; |
|
83 |
else |
|
84 |
pRGBArray[i] |= orColor; |
|
85 |
} |
|
86 |
if (debug) |
|
87 |
System.out.println(""); |
|
88 |
} |
|
89 |
} |
|
90 |
|
|
91 |
class SimplePixelFilter extends PixelFilter { |
|
92 |
public SimplePixelFilter(int alpha) { |
|
93 |
super(alpha); |
|
94 |
} |
|
95 |
public void filterLine(int [] pRGBArray) { |
|
96 |
for (int i=0; i<pRGBArray.length; i++) { |
|
97 |
if (debug) |
|
98 |
System.out.print(""+i+":"+Integer.toHexString(pRGBArray[i])+","); |
|
99 |
pRGBArray[i] |= orColor; |
|
100 |
} |
|
101 |
if (debug) |
|
102 |
System.out.println(""); |
|
103 |
} |
|
104 |
} |
|
105 |
|
|
106 | 22 |
/** |
107 | 23 |
* Soporte para los ficheros .ecw de ErMapper. |
108 | 24 |
* <br> |
... | ... | |
138 | 54 |
private String errorMessage = null; |
139 | 55 |
|
140 | 56 |
private Extent v = null; |
141 |
private boolean doTransparency = false; |
|
142 |
private int alpha = 0; |
|
143 |
private PixelFilter tFilter = null; |
|
144 | 57 |
|
145 | 58 |
// Ultimo porcentaje de refresco. Se carga en el update y se |
146 | 59 |
// actualiza en el refreshUpdate |
... | ... | |
216 | 129 |
public int getHeight() { return file.height; } |
217 | 130 |
|
218 | 131 |
/** |
219 |
* Trozo de imagen en que se divide la consulta a la librer?a, |
|
132 |
* Trozo de imagen (Chunk) en que se divide la consulta a la librer?a,
|
|
220 | 133 |
* para esquivar el bug#2. |
221 | 134 |
* |
222 | 135 |
* @author luisw |
223 | 136 |
*/ |
224 | 137 |
static class ChunkFrame { |
225 | 138 |
// Ancho m?ximo (~2500 px) |
226 |
final static int MAX_WIDTH = 1024;
|
|
139 |
final static int MAX_WIDTH = 1536;
|
|
227 | 140 |
// Alto m?ximo (no hay l?mite) |
228 | 141 |
final static int MAX_HEIGHT = 20000; |
229 | 142 |
Point pos; |
... | ... | |
261 | 174 |
// TODO Mejorarlo para que los PAN con un zoom muy grande sean correctos |
262 | 175 |
if ((ptMax.x-ptMin.x)<sz.width) { |
263 | 176 |
numCol = numRow = 1; |
264 |
frames[0] = new ChunkFrame(v, ptMax.x-ptMin.x, ptMin.y-ptMax.y); |
|
177 |
f = frames[0] = new ChunkFrame(v, ptMax.x-ptMin.x, ptMin.y-ptMax.y);
|
|
265 | 178 |
System.out.println("Size=("+f.width+","+f.height+")"); |
266 |
frames[0].mustResize = true; |
|
179 |
f.pos = new Point(0,0); |
|
180 |
f.mustResize = true; |
|
181 |
f.v = new Extent(v); |
|
267 | 182 |
} else { |
268 | 183 |
// Calcula cada chunk |
184 |
double step = ((double) ptMax.x-ptMin.x)/sz.getWidth(); |
|
185 |
int h = sz.height; |
|
269 | 186 |
for (int r=0; r<numRow; r++) { |
187 |
int w = sz.width; |
|
270 | 188 |
for (int c = 0; c<numCol; c++) { |
271 | 189 |
f = new ChunkFrame(null, -1, -1); |
272 | 190 |
// Posici?n del chunk |
273 | 191 |
f.pos = new Point(c*MAX_WIDTH, r*MAX_HEIGHT); |
274 | 192 |
// Tama?o del chunk |
275 |
f.width = Math.min(MAX_WIDTH, sz.width);
|
|
276 |
f.height = Math.min(MAX_WIDTH, sz.height);
|
|
193 |
f.width = Math.min(MAX_WIDTH, w);
|
|
194 |
f.height = Math.min(MAX_WIDTH, h);
|
|
277 | 195 |
// Extent del chunk |
196 |
int x1 = ptMin.x+(int) (f.pos.x*step); |
|
197 |
int x2 = x1+(int)(f.width*step); |
|
198 |
int y1 = ptMax.y; |
|
199 |
int y2 = ptMin.y; |
|
200 |
JNCSWorldPoint pt1 = file.convertDatasetToWorld(x1, y1); |
|
201 |
JNCSWorldPoint pt2 = file.convertDatasetToWorld(x2, y2); |
|
202 |
f.v = new Extent(pt1.x, pt1.y, pt2.x, pt2.y); // Hay que calcularlo |
|
203 |
System.out.println(" View DataSet = ("+x1+","+y1+","+x2+","+y2+")"); |
|
204 |
System.out.println(" View Extent = "+ v); |
|
205 |
System.out.println("Frame Extent = "+ f.v); |
|
206 |
|
|
278 | 207 |
frames[r*numCol+c] = f; |
208 |
w -= MAX_WIDTH; |
|
279 | 209 |
} |
210 |
h -= MAX_HEIGHT; |
|
280 | 211 |
} |
281 | 212 |
} |
213 |
System.out.println("Hay "+numRow+" filas y "+numCol+" columnas."); |
|
282 | 214 |
return frames; |
283 | 215 |
} |
284 | 216 |
} |
... | ... | |
314 | 246 |
} |
315 | 247 |
|
316 | 248 |
fullSize = new Dimension(width, height); |
317 |
// Create an image of the ecw file. |
|
318 |
if (doTransparency) |
|
319 |
ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
|
320 |
else |
|
321 |
ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
|
322 |
|
|
249 |
// Peta en los peque?os ... arreglar antes de meter del todo |
|
323 | 250 |
ChunkFrame frames[] = ChunkFrame.computeFrames(file, v, fullSize); |
251 |
if (frames.length == 1) { |
|
252 |
width = frames[0].width; height = frames[0].height; |
|
253 |
//System.out.println("Cambio el ancho total a ("+width+","+height+")"); |
|
254 |
} |
|
324 | 255 |
|
325 |
JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY()); |
|
256 |
/* JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY());
|
|
326 | 257 |
JNCSDatasetPoint ptMax = file.convertWorldToDataset(v.maxX(), v.maxY()); |
327 | 258 |
System.out.println("Dataset coords Width = "+(ptMax.x-ptMin.x)+", px width ="+width); |
328 | 259 |
// BEGIN Cambiando para soportar e < 1:1 |
... | ... | |
332 | 263 |
height = ptMin.y-ptMax.y; |
333 | 264 |
System.out.println("Size=("+width+","+height+")"); |
334 | 265 |
mustResize = true; |
335 |
} |
|
336 |
// END Cambiando para soportar e < 1:1 |
|
266 |
}*/ |
|
267 |
// Create an image of the ecw file. |
|
268 |
if (doTransparency) |
|
269 |
ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
|
270 |
else |
|
271 |
ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
|
337 | 272 |
|
338 | 273 |
pRGBArray = new int[width]; |
339 | 274 |
|
... | ... | |
343 | 278 |
bandlist[i] = i; |
344 | 279 |
} |
345 | 280 |
|
346 |
// Set the view |
|
347 |
file.setView(file.numBands, bandlist, |
|
348 |
v.minX(), v.maxY(), v.maxX(), v.minY(), |
|
349 |
width, height); |
|
350 |
|
|
351 |
// Read the scan lines |
|
352 |
for (line=0; line < height; line++) { |
|
353 |
file.readLineRGBA(pRGBArray); |
|
354 |
// Prueba de sustituci?n de color transparente |
|
355 |
if (doTransparency) { |
|
356 |
if (line == 0) tFilter.debug = true; |
|
357 |
tFilter.filterLine(pRGBArray); |
|
358 |
tFilter.debug = false; |
|
281 |
for (int nChunk=0; nChunk<frames.length; nChunk++) { |
|
282 |
ChunkFrame f = frames[nChunk]; |
|
283 |
// Set the view |
|
284 |
file.setView(file.numBands, bandlist, |
|
285 |
f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), |
|
286 |
f.width, f.height); |
|
287 |
|
|
288 |
// Read the scan lines |
|
289 |
for (line=0; line < height; line++) { |
|
290 |
file.readLineRGBA(pRGBArray); |
|
291 |
// Prueba de sustituci?n de color transparente |
|
292 |
if (doTransparency) { |
|
293 |
if (line == 0) tFilter.debug = true; |
|
294 |
tFilter.filterLine(pRGBArray); |
|
295 |
tFilter.debug = false; |
|
296 |
} |
|
297 |
//System.out.println("setRGB("+f.pos.x+","+f.pos.y+line+","+f.width+","+1+","+pRGBArray+","+0+","+f.width+")"); |
|
298 |
((BufferedImage)ecwImage).setRGB(f.pos.x, f.pos.y+line, f.width, 1, pRGBArray, 0, f.width); |
|
359 | 299 |
} |
360 |
((BufferedImage)ecwImage).setRGB(0, line, width, 1, pRGBArray, 0, width); |
|
361 | 300 |
} |
301 |
if (frames[0].mustResize) { |
|
302 |
//System.out.println("resize "+fullSize); |
|
303 |
return resizeImage(fullSize, ecwImage); |
|
304 |
} |
|
362 | 305 |
/* |
363 | 306 |
* La excepci?n atrapada es la de 'zoom > 1:1 no valido' |
364 | 307 |
} catch (com.ermapper.ecw.JNCSInvalidSetViewException e) { |
... | ... | |
372 | 315 |
e.printStackTrace(); |
373 | 316 |
} |
374 | 317 |
lastRefreshPercent = file.getPercentComplete(); |
375 |
if (mustResize) { |
|
376 |
return resizeImage(fullSize, ecwImage); |
|
377 |
} |
|
378 | 318 |
return ecwImage; |
379 | 319 |
} |
380 | 320 |
|
Also available in: Unified diff