Revision 6315

View differences:

org.gvsig.raster/branches/org.gvsig.raster.2.4/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.legend/org.gvsig.raster.lib.legend.impl/src/main/java/org/gvsig/raster/lib/legend/impl/DefaultRasterLegend.java
2 2

  
3 3
import java.awt.Graphics;
4 4
import java.awt.Image;
5
import java.awt.color.ColorSpace;
6
import java.awt.color.ICC_ColorSpace;
7
import java.awt.color.ICC_Profile;
5 8
import java.awt.geom.AffineTransform;
6 9
import java.awt.geom.NoninvertibleTransformException;
7 10
import java.awt.image.BufferedImage;
8 11

  
12
import org.apache.log4j.spi.AppenderAttachable;
9 13
import org.cresques.cts.ICoordTrans;
10 14
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
11 15
import org.gvsig.fmap.geom.GeometryLocator;
......
204 208
        Image image = null;
205 209
        if (this.colorInterpretation.isGray()){
206 210
             // Draw buffer with gray scale
207
            image = drawBuffer(graphics, bufferToDraw, filters);
211
            image = drawGrayBuffer(graphics, bufferToDraw, transparency, filters);
208 212
        }else if ( this.colorInterpretation.isPalette() && this.colorTable != null ) {
209 213
            // Draw buffer with table color
210
            image = drawBuffer(graphics, bufferToDraw, colorTable, transparency, filters);
211

  
214
            image = drawPaletteBuffer(graphics, bufferToDraw, colorTable, transparency, filters);
212 215
        } else if (this.colorInterpretation.isRGBA() || this.colorInterpretation.isRGB()
213 216
            || this.colorInterpretation.isBGR()) {
214

  
215 217
            // Draw RGB, RGBA or BGR buffer without color table
216
            image = drawBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
218
            image = drawRGBBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
219
        }else if (this.colorInterpretation.isHSL()) {
220
            // Draw HSL buffer without color table
221
            image = drawHSLBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
222
        }else if (this.colorInterpretation.isCMYK()) {
223
            // Draw CMYK buffer without color table
224
            image = drawCMYKBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
225
        }else if (this.colorInterpretation.isYCBCR()) {
226
            // Draw YCBCR buffer without color table
227
            image = drawYCBCRBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
217 228
        }
218 229

  
219 230
        // Calculate where image has to be drawn
......
261 272
        return heightEnvelope / dist1pixel;
262 273
    }
263 274

  
264
    private Image drawBuffer(Graphics graphics, Buffer buffer,
275

  
276

  
277
    private Image drawRGBBuffer(Graphics graphics, Buffer buffer,
265 278
        ColorInterpretation colorInterpretation, Transparency transparency, FilterList filters) {
266 279

  
267 280
        BufferedImage image = null;
......
311 324
                    alphaValue = alphaValue.byteValue() & 0xFF;
312 325
                    int newAlpha =
313 326
                        transparency.getTransparencyRangeAlpha(redValue.byteValue(),
314
                            blueValue.byteValue(), greenValue.byteValue());
327
                            greenValue.byteValue(), blueValue.byteValue());
315 328
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
316 329

  
317 330
                    // Apply general transparency
......
341 354
        return image;
342 355
    }
343 356

  
357

  
358
    private Image drawHSLBuffer(Graphics graphics, Buffer buffer,
359
        ColorInterpretation colorInterpretation,Transparency transparency,
360
        FilterList filters) {
361

  
362
        BufferedImage image = null;
363

  
364
        image =
365
            new BufferedImage(buffer.getColumns(), buffer.getRows(),
366
                BufferedImage.TYPE_INT_ARGB);
367

  
368
        int hueBandIndex = colorInterpretation.getBand(ColorInterpretation.HUE_BAND);
369
        int saturationBandIndex = colorInterpretation.getBand(ColorInterpretation.SATURATION_BAND);
370
        int lightBandIndex = colorInterpretation.getBand(ColorInterpretation.LIGHTNESS_BAND);
371

  
372

  
373
        Band hueBand = buffer.getBand(hueBandIndex);
374
        Band saturationBand = buffer.getBand(saturationBandIndex);
375
        Band lightBand = buffer.getBand(lightBandIndex);
376

  
377

  
378
        for (int i = 0; i < buffer.getRows(); i++) {
379
            for (int j = 0; j < buffer.getColumns(); j++) {
380
                Number hueValue = (Number) hueBand.get(i, j);
381
                Number saturationValue = (Number) saturationBand.get(i, j);
382
                Number lightValue = (Number) lightBand.get(i, j);
383

  
384
                Number[] rgbaValues=ColorUtils.fromHSLtoRGBA(hueValue.floatValue(), saturationValue.floatValue(), lightValue.floatValue());
385

  
386
                Integer alphaValue =rgbaValues[3].intValue();
387
                if (transparency != null) {
388
                    // Apply defined transparency ranges
389

  
390
                    alphaValue = alphaValue.byteValue() & 0xFF;
391
                    int newAlpha =
392
                        transparency.getTransparencyRangeAlpha(rgbaValues[0].byteValue(),
393
                            rgbaValues[1].byteValue(), rgbaValues[2].byteValue());
394
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
395

  
396
                    // Apply general transparency
397
                    int transparencyValue = transparency.getAlpha();
398
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
399
                }
400

  
401
                if (filters != null) {
402
                    // TODO Apply filters
403
                }
404

  
405
                int intRGB = 0;
406
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
407
                    ((rgbaValues[0].byteValue() & 0xFF) << 16) | // red
408
                    ((rgbaValues[1].byteValue() & 0xFF) << 8) | // green
409
                    ((rgbaValues[2].byteValue() & 0xFF) << 0); // blue
410
                image.setRGB(j, i, intRGB);
411
            }
412
        }
413
        return image;
414
    }
415

  
416
    private Image drawCMYKBuffer(Graphics graphics, Buffer buffer,
417
        ColorInterpretation colorInterpretation,Transparency transparency,
418
        FilterList filters) {
419

  
420
        BufferedImage image = null;
421

  
422
        image =
423
            new BufferedImage(buffer.getColumns(), buffer.getRows(),
424
                BufferedImage.TYPE_INT_ARGB);
425

  
426
        int cyanBandIndex = colorInterpretation.getBand(ColorInterpretation.CYAN_BAND);
427
        int magentaBandIndex = colorInterpretation.getBand(ColorInterpretation.MAGENTA_BAND);
428
        int yellowBandIndex = colorInterpretation.getBand(ColorInterpretation.YELLOW_BAND);
429
        int blackBandIndex = colorInterpretation.getBand(ColorInterpretation.BLACK_BAND);
430

  
431

  
432
        Band cyanBand = buffer.getBand(cyanBandIndex);
433
        Band magentaBand = buffer.getBand(magentaBandIndex);
434
        Band yellowBand = buffer.getBand(yellowBandIndex);
435
        Band blackBand = buffer.getBand(blackBandIndex);
436

  
437
        for (int i = 0; i < buffer.getRows(); i++) {
438
            for (int j = 0; j < buffer.getColumns(); j++) {
439
                Number cyanValue = (Number) cyanBand.get(i, j);
440
                Number magentaValue = (Number) magentaBand.get(i, j);
441
                Number yellowValue = (Number) yellowBand.get(i, j);
442
                Number blackValue = (Number) blackBand.get(i, j);
443

  
444

  
445

  
446
                Number[] rgbValues=ColorUtils.fromCMYKtoRGB(
447
                    cyanValue.floatValue(),
448
                    magentaValue.floatValue(),
449
                    yellowValue.floatValue(),
450
                    blackValue.floatValue()
451
                    );
452

  
453
                Integer alphaValue =255;
454
                if (transparency != null) {
455
                    // Apply defined transparency ranges
456

  
457
                    alphaValue = alphaValue.byteValue() & 0xFF;
458
                    int newAlpha =
459
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
460
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
461
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
462

  
463
                    // Apply general transparency
464
                    int transparencyValue = transparency.getAlpha();
465
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
466
                }
467

  
468
                if (filters != null) {
469
                    // TODO Apply filters
470
                }
471

  
472
                int intRGB = 0;
473
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
474
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
475
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
476
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
477
                image.setRGB(j, i, intRGB);
478
            }
479
        }
480
        return image;
481
    }
482

  
483
    private Image drawYCBCRBuffer(Graphics graphics, Buffer buffer,
484
        ColorInterpretation colorInterpretation,Transparency transparency,
485
        FilterList filters) {
486

  
487
        BufferedImage image = null;
488

  
489
        image =
490
            new BufferedImage(buffer.getColumns(), buffer.getRows(),
491
                BufferedImage.TYPE_INT_ARGB);
492

  
493
        int yIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_Y_BAND);
494
        int cbBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CB_BAND);
495
        int crBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CR_BAND);
496

  
497

  
498
        Band yBand = buffer.getBand(yIndex);
499
        Band cbBand = buffer.getBand(cbBandIndex);
500
        Band crBand = buffer.getBand(crBandIndex);
501

  
502
        for (int i = 0; i < buffer.getRows(); i++) {
503
            for (int j = 0; j < buffer.getColumns(); j++) {
504
                Number yValue = (Number) yBand.get(i, j);
505
                Number cbValue = (Number) cbBand.get(i, j);
506
                Number crValue = (Number) crBand.get(i, j);
507

  
508
                Number[] rgbValues=ColorUtils.fromYCBCRtoRGB(
509
                    yValue.floatValue(),
510
                    cbValue.floatValue(),
511
                    crValue.floatValue()
512
                    );
513

  
514
                Integer alphaValue =255;
515
                if (transparency != null) {
516
                    // Apply defined transparency ranges
517

  
518
                    alphaValue = alphaValue.byteValue() & 0xFF;
519
                    int newAlpha =
520
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
521
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
522
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
523

  
524
                    // Apply general transparency
525
                    int transparencyValue = transparency.getAlpha();
526
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
527
                }
528

  
529
                if (filters != null) {
530
                    // TODO Apply filters
531
                }
532

  
533
                int intRGB = 0;
534
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
535
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
536
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
537
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
538
                image.setRGB(j, i, intRGB);
539
            }
540
        }
541
        return image;
542
    }
543

  
344 544
    /**
345 545
     * Method to draw gray buffers
346 546
     * @param graphics
......
348 548
     * @param filters
349 549
     * @return
350 550
     */
351
    private Image drawBuffer(Graphics graphics, Buffer buffer, FilterList filters) {
551
    private Image drawGrayBuffer(Graphics graphics, Buffer buffer, Transparency transparency, FilterList filters) {
352 552

  
353 553
        BufferedImage image = null;
354 554

  
355 555
        image =
356
            new BufferedImage(buffer.getColumns(), buffer.getRows(), BufferedImage.TYPE_INT_BGR);
556
            new BufferedImage(buffer.getColumns(), buffer.getRows(), BufferedImage.TYPE_INT_ARGB);
357 557

  
358 558
        Band greyBand = buffer.getBand(0);
359 559

  
......
361 561
            for (int j = 0; j < buffer.getColumns(); j++) {
362 562
                Number greyValue = (Number) greyBand.get(i, j);
363 563

  
564
                Integer alphaValue =255;
565
                if (transparency != null) {
566
                    // Apply defined transparency ranges
567

  
568
                    alphaValue = alphaValue.byteValue() & 0xFF;
569
                    int newAlpha =
570
                        transparency.getTransparencyRangeAlpha(greyValue.byteValue(),
571
                            greyValue.byteValue(), greyValue.byteValue());
572
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
573

  
574
                    // Apply general transparency
575
                    int transparencyValue = transparency.getAlpha();
576
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
577
                }
578

  
364 579
                if (filters != null) {
365 580
                    // TODO Apply filters
366 581
                }
367 582

  
368
                int intRGB =((greyValue.byteValue() & 0xFF) << 16 | // blue
583
                int intARGB = ((alphaValue.byteValue()  & 0xFF) << 24) | // alpha
584
                    ((greyValue.byteValue() & 0xFF) << 16) | // red
369 585
                    ((greyValue.byteValue() & 0xFF) << 8) | // green
370
                    ((greyValue.byteValue() & 0xFF) << 0)); // red
586
                    ((greyValue.byteValue() & 0xFF) << 0); // blue
371 587

  
372
                image.setRGB(j, i, intRGB);
588
                image.setRGB(j, i, intARGB);
373 589
            }
374 590
        }
375 591
        return image;
376 592
    }
377 593

  
378
    private Image drawBuffer(Graphics graphics, Buffer buffer, ColorTable colorTable,
594
    private Image drawPaletteBuffer(Graphics graphics, Buffer buffer, ColorTable colorTable,
379 595
        Transparency transparency, FilterList filters) {
380 596

  
381 597
        BufferedImage image =
org.gvsig.raster/branches/org.gvsig.raster.2.4/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.legend/org.gvsig.raster.lib.legend.impl/src/main/java/org/gvsig/raster/lib/legend/impl/ColorUtils.java
1
package org.gvsig.raster.lib.legend.impl;
2

  
3
import java.awt.Color;
4

  
5
/**
6
 * Utility class to color conversions
7
 * @author dmartinezizquierdo
8
 *
9
 */
10
public class ColorUtils {
11

  
12
    /**
13
     *
14
     * @param y
15
     * @param cb
16
     * @param cr
17
     * @return the RGB values
18
     */
19
    public static Number[] fromYCBCRtoRGB(float y, float cb, float cr){
20
        Number[] rgbValues = new Number[3];
21

  
22
        int r = (int) (y + 1.40200 * (cr - 0x80));
23
        int g = (int) (y - 0.34414 * (cb - 0x80) - 0.71414 * (cr - 0x80));
24
        int b = (int) (y + 1.77200 * (cb - 0x80));
25

  
26
        rgbValues[0] = Math.max(0, Math.min(255, r));
27
        rgbValues[1] = Math.max(0, Math.min(255, g));
28
        rgbValues[2] = Math.max(0, Math.min(255, b));
29

  
30
        return rgbValues;
31
    }
32

  
33
    /**
34
     * Convert CMYK values to RGB values
35
     * NOTE: Conversion maybe very inaccurate
36
     *
37
     * @param cyan
38
     * @param magenta
39
     * @param yellow
40
     * @param black
41
     * @return the RGB values
42
     */
43
    public static Number[] fromCMYKtoRGB(float cyan, float magenta, float yellow, float black){
44
        //TODO: ICC profiles should be used to more precise conversion, as shown here:
45
        //http://stackoverflow.com/questions/3123574/how-to-convert-from-cmyk-to-rgb-in-java-correctly
46
        Number[] rgbValues = new Number[3];
47

  
48
        float colors = 255 - black;
49
        rgbValues[0] = colors * (255 - cyan) / 255;
50
        rgbValues[1] = colors * (255 - magenta) / 255;
51
        rgbValues[2] = colors * (255 - yellow) / 255;
52
        return rgbValues;
53
    }
54

  
55
    /**
56
     *  Convert HSL values to RGBA values with a default alpha value of 1.
57
     *
58
     *  @param h Hue is specified as degrees in the range 0 - 360.
59
     *  @param s Saturation is specified as a percentage in the range 1 - 100.
60
     *  @param l Lumanance is specified as a percentage in the range 1 - 100.
61
     *
62
     *  @returns the RGBA values
63
     */
64
    public static Number[] fromHSLtoRGBA(float h, float s, float l)
65
    {
66
        return fromHSLtoRGBA(h, s, l, 1.0f);
67
    }
68

  
69
    /**
70
     *  Convert HSL values to RGBA values
71
     *
72
     *  @param h Hue is specified as degrees in the range 0 - 360.
73
     *  @param s Saturation is specified as a percentage in the range 1 - 100.
74
     *  @param l Lumanance is specified as a percentage in the range 1 - 100.
75
     *  @param alpha  the alpha value between 0 - 1
76
     *
77
     *  @returns the RGBA values
78
     */
79
    public static Number[] fromHSLtoRGBA(float h, float s, float l, float alpha)
80
    {
81
        if (s <0.0f || s > 100.0f)
82
        {
83
            String message = "Color parameter outside of expected range - Saturation";
84
            throw new IllegalArgumentException( message );
85
        }
86

  
87
        if (l <0.0f || l > 100.0f)
88
        {
89
            String message = "Color parameter outside of expected range - Luminance";
90
            throw new IllegalArgumentException( message );
91
        }
92

  
93
        if (alpha <0.0f || alpha > 1.0f)
94
        {
95
            String message = "Color parameter outside of expected range - Alpha";
96
            throw new IllegalArgumentException( message );
97
        }
98

  
99
        //  Formula needs all values between 0 - 1.
100

  
101
        h = h % 360.0f;
102
        h /= 360f;
103
        s /= 100f;
104
        l /= 100f;
105

  
106
        float q = 0;
107

  
108
        if (l < 0.5)
109
            q = l * (1 + s);
110
        else
111
            q = (l + s) - (s * l);
112

  
113
        float p = 2 * l - q;
114

  
115
        float r = Math.max(0, HueToRGB(p, q, h + (1.0f / 3.0f)));
116
        float g = Math.max(0, HueToRGB(p, q, h));
117
        float b = Math.max(0, HueToRGB(p, q, h - (1.0f / 3.0f)));
118

  
119
        r = Math.min(r, 1.0f);
120
        g = Math.min(g, 1.0f);
121
        b = Math.min(b, 1.0f);
122

  
123
        Number[] rgbValues=new Number[4];
124
        rgbValues[0]=r;
125
        rgbValues[1]=g;
126
        rgbValues[2]=b;
127
        rgbValues[3]=alpha;
128
        return rgbValues;
129
    }
130

  
131
    private static float HueToRGB(float p, float q, float h)
132
    {
133
        if (h < 0) h += 1;
134

  
135
        if (h > 1 ) h -= 1;
136

  
137
        if (6 * h < 1)
138
        {
139
            return p + ((q - p) * 6 * h);
140
        }
141

  
142
        if (2 * h < 1 )
143
        {
144
            return  q;
145
        }
146

  
147
        if (3 * h < 2)
148
        {
149
            return p + ( (q - p) * 6 * ((2.0f / 3.0f) - h) );
150
        }
151

  
152
        return p;
153
    }
154
}

Also available in: Unified diff