/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2015, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.processing.image.dynamicrange; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import org.apache.sis.util.ArgumentChecks; import org.geotoolkit.image.iterator.PixelIterator; import org.geotoolkit.image.iterator.PixelIteratorFactory; import org.geotoolkit.math.XMath; import org.geotoolkit.parameter.Parameters; import org.geotoolkit.utility.parameter.ParametersExt; import org.geotoolkit.processing.AbstractProcess; import org.geotoolkit.process.ProcessException; import static org.geotoolkit.processing.image.dynamicrange.DynamicRangeStretchDescriptor.*; import org.opengis.parameter.ParameterValueGroup; /** * * @author Johann Sorel (Geomatys) */ public class DynamicRangeStretchProcess extends AbstractProcess { public DynamicRangeStretchProcess(RenderedImage input, int[] bands, double[][] ranges) { super(INSTANCE, asParameters(input,bands,ranges)); } private static ParameterValueGroup asParameters(RenderedImage input, int[] bands, double[][] ranges){ final ParameterValueGroup params = DynamicRangeStretchDescriptor.INPUT_DESC.createValue(); ParametersExt.getOrCreateValue(params, IN_IMAGE.getName().getCode()).setValue(input); ParametersExt.getOrCreateValue(params, IN_BANDS.getName().getCode()).setValue(bands); ParametersExt.getOrCreateValue(params, IN_RANGES.getName().getCode()).setValue(ranges); return params; } public DynamicRangeStretchProcess(ParameterValueGroup input) { super(INSTANCE, input); } public BufferedImage executeNow() throws ProcessException { execute(); return (BufferedImage) outputParameters.parameter(OUT_IMAGE.getName().getCode()).getValue(); } @Override protected void execute() throws ProcessException { ArgumentChecks.ensureNonNull("inputParameter", inputParameters); final RenderedImage inputImage = (RenderedImage) Parameters.getOrCreate(IN_IMAGE, inputParameters).getValue(); final int[] bands = (int[]) Parameters.getOrCreate(IN_BANDS, inputParameters).getValue(); final double[][] ranges = (double[][]) Parameters.getOrCreate(IN_RANGES, inputParameters).getValue(); if(bands.length!=4 || ranges.length!=4){ throw new ProcessException("Bands and Ranges parameters must be of size 4.", this); } final SampleModel inputSampleModel = inputImage.getSampleModel(); final int inputNbBand = inputSampleModel.getNumBands(); final BufferedImage resultImage = new BufferedImage(inputImage.getWidth(), inputImage.getHeight(), BufferedImage.TYPE_INT_ARGB); final WritableRaster raster = resultImage.getRaster(); for (int i=0;i<bands.length;i++) { if (bands[i] > (inputNbBand-1)) { throw new ProcessException("Unvalid configuration, band "+bands[i]+" do not exist.", this); } } //copy datas final PixelIterator readIte = PixelIteratorFactory.createDefaultIterator(inputImage); final PixelIterator writeIte = PixelIteratorFactory.createDefaultWriteableIterator(raster, raster); final double[] pixel = new double[inputNbBand]; final int[] rgba = new int[4]; int srcBandIdx; int trgBandIdx; while (readIte.next() && writeIte.next()) { srcBandIdx = 0; trgBandIdx = 0; //read source pixels pixel[srcBandIdx] = readIte.getSampleDouble(); while (++srcBandIdx != inputNbBand) { readIte.next(); pixel[srcBandIdx] = readIte.getSampleDouble(); } //calculate color boolean hasNan = false; for(int i=0;i<rgba.length;i++){ if(bands[i]==-1){ //default value rgba[i] = (i==3)?255:0; }else{ //calculate value double v = pixel[bands[i]]; if(Double.isNaN(v)){ hasNan = true; } v = (pixel[bands[i]]-ranges[i][0]) / (ranges[i][1]-ranges[i][0]) * 255; rgba[i] = XMath.clamp((int)v, 0, 255); } } if(hasNan){ rgba[0]=0;rgba[1]=0;rgba[2]=0;rgba[3]=0; } //write target pixels writeIte.setSampleDouble(rgba[trgBandIdx]); while (++trgBandIdx != bands.length) { writeIte.next(); writeIte.setSampleDouble(rgba[trgBandIdx]); } } Parameters.getOrCreate(OUT_IMAGE, outputParameters).setValue(resultImage); } }