/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.geosolutions.jaiext.binarize; import it.geosolutions.jaiext.range.Range; import java.awt.RenderingHints; import java.awt.image.RenderedImage; import java.awt.image.renderable.ParameterBlock; import java.awt.image.renderable.RenderableImage; import javax.media.jai.JAI; import javax.media.jai.OperationDescriptorImpl; import javax.media.jai.ParameterBlockJAI; import javax.media.jai.ROI; import javax.media.jai.RenderableOp; import javax.media.jai.RenderedOp; import javax.media.jai.registry.RenderableRegistryMode; import javax.media.jai.registry.RenderedRegistryMode; /** * An <code>OperationDescriptor</code> describing the "Binarize" operation. * * <p> The "Binarize" operation takes one rendered or renderable single-banded * source image and a threshold value and applies a thresholding operation to * the produce a bilevel image. Users can define ROI on where the pixel must be * calculated, keeping external pixel to 0. Also it is possible to define a nodata * variable for setting NoData values always to 0. * * <p> By default the destination image bounds are equal to those of the * source image. The <code>SampleModel</code> of the destination image is * an instance of <code>MultiPixelPackedSampleModel</code>. * * <p> The pseudocode for "Binarize" is as follows: * <pre> * dst(x, y) = src(x, y) >= threshold ? 1 : 0; * </pre> * * <p><table border=1> * <caption>Resource List</caption> * <tr><th>Name</th> <th>Value</th></tr> * <tr><td>GlobalName</td> <td>Binarize</td></tr> * <tr><td>LocalName</td> <td>Binarize</td></tr> * <tr><td>Vendor</td> <td>it.geosolutions.jaiext</td></tr> * <tr><td>Description</td> <td>Thresholds a single banded image into a bilevel image.<td></tr> * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/BinarizeDescriptor.html</td></tr> * <tr><td>Version</td> <td>1.1</td></tr> * <tr><td>arg0Desc</td> <td>The threshold value.</td></tr> * <tr><td>arg1Desc</td> <td>The ROI value.</td></tr> * <tr><td>arg2Desc</td> <td>The nodata value.</td></tr> * </table></p> * * <p><table border=1> * <caption>Parameter List</caption> * <tr><th>Name</th> <th>Class Type</th> * <th>Default Value</th></tr> * <tr><td>threshold</td> <td>java.lang.Double</td> * <td>NO_PARAMETER_DEFAULT</td> * <tr><td>roi</td> <td>javax.media.jai.ROI</td> * <td>null</td> * <tr><td>nodata</td> <td>it.geosolutions.jaiext.range.Range</td> * <td>null</td> * </table></p> */ public class BinarizeDescriptor extends OperationDescriptorImpl { /** * The resource strings that provide the general documentation */ private static final String[][] resources = { {"GlobalName", "Binarize"}, {"LocalName", "Binarize"}, {"Vendor", "it.geosolutions.jaiext"}, {"Description", JaiI18N.getString("BinarizeDescriptor0")}, {"DocURL", "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/BinarizeDescriptor.html"}, {"Version", JaiI18N.getString("DescriptorVersion")}, {"arg0Desc", JaiI18N.getString("BinarizeDescriptor2")}, {"arg1Desc", JaiI18N.getString("BinarizeDescriptor3")}, {"arg2Desc", JaiI18N.getString("BinarizeDescriptor4")} }; /** The parameter name list*/ private static final String[] paramNames = { "threshold", "roi", "nodata" }; /** * The parameter class list for this operation. */ private static final Class[] paramClasses = { java.lang.Double.class, javax.media.jai.ROI.class, it.geosolutions.jaiext.range.Range.class }; /** The parameter default value list*/ private static final Object[] paramDefaults = { NO_PARAMETER_DEFAULT, null, null }; private static final String[] supportedModes = { "rendered", "renderable" }; /** Constructor. */ public BinarizeDescriptor() { super(resources, supportedModes, 1, paramNames, paramClasses, paramDefaults, null); } /** * Validates the input source. * * <p> It also checks if the input image is single banded */ protected boolean validateSources(String modeName, ParameterBlock args, StringBuffer msg) { if (!super.validateSources(modeName, args, msg)) { return false; } // No check for not-rendered modes if (!modeName.equalsIgnoreCase("rendered")) return true; RenderedImage source = (RenderedImage)(args.getSource(0)); int numBands = source.getSampleModel().getNumBands(); if (numBands != 1){ msg.append(getName() + " " + JaiI18N.getString("BinarizeDescriptor1")); return false; } return true; } /** * Binarize an image from a threshold value, taking into account the presence of ROI and NoData * * <p>Creates a <code>ParameterBlockJAI</code> from all * supplied arguments except <code>hints</code> and invokes * {@link JAI#create(String,ParameterBlock,RenderingHints)}. * * @see JAI * @see ParameterBlockJAI * @see RenderedOp * * @param source0 <code>RenderedImage</code> source 0. * @param threshold It must be of type java.lang.Double. * @param roi ROI object. * @param nodata NoData Range to use in calculation. * @param hints The <code>RenderingHints</code> to use. * May be <code>null</code>. * @return The <code>RenderedOp</code> destination. * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>. * @throws IllegalArgumentException if <code>threshold</code> is <code>null</code>. */ public static RenderedOp create(RenderedImage source0, Double threshold, ROI roi, Range nodata, RenderingHints hints) { ParameterBlockJAI pb = new ParameterBlockJAI("Binarize", RenderedRegistryMode.MODE_NAME); // Setting source pb.setSource("source0", source0); // Setting parameter pb.setParameter("threshold", threshold); pb.setParameter("roi", roi); pb.setParameter("nodata", nodata); // Creating the RenderedOp return JAI.create("Binarize", pb, hints); } /** * Binarize an image from a threshold value, taking into account the presence of ROI and NoData * * <p>Creates a <code>ParameterBlockJAI</code> from all * supplied arguments except <code>hints</code> and invokes * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}. * * @see JAI * @see ParameterBlockJAI * @see RenderableOp * * @param source0 <code>RenderableImage</code> source 0. * @param threshold Argment must be of type java.lang.Double. * @param roi ROI object. * @param nodata NoData Range to use in calculation. * @param hints The <code>RenderingHints</code> to use. * May be <code>null</code>. * @return The <code>RenderableOp</code> destination. * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>. * @throws IllegalArgumentException if <code>threshold</code> is <code>null</code>. */ public static RenderableOp createRenderable(RenderableImage source0, Double threshold, ROI roi, Range nodata, RenderingHints hints) { ParameterBlockJAI pb = new ParameterBlockJAI("Binarize", RenderableRegistryMode.MODE_NAME); // Setting source pb.setSource("source0", source0); // Setting parameters pb.setParameter("threshold", threshold); pb.setParameter("roi", roi); pb.setParameter("nodata", nodata); // Creating the Renderable parameter return JAI.createRenderable("Binarize", pb, hints); } }