/* * This file is part of JGrasstools (http://www.jgrasstools.org) * (C) HydroloGIS - www.hydrologis.com * * JGrasstools is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.jgrasstools.gears.utils.images; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.IOException; import java.util.Hashtable; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.coverage.grid.io.AbstractGridFormat; import org.geotools.coverage.processing.Operations; import org.geotools.geometry.DirectPosition2D; import org.geotools.geometry.Envelope2D; import org.geotools.parameter.Parameter; import org.opengis.geometry.Envelope; import org.opengis.parameter.GeneralParameterValue; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * An utility class image handling. * * @author Andrea Antonello (www.hydrologis.com) * @since 0.7.9 */ public class ImageUtilities { /** * Scale an image to a given size maintaining the ratio. * * @param image the image to scale. * @param newSize the size of the new image (it will be used for the longer side). * @return the scaled image. * @throws Exception */ public static BufferedImage scaleImage( BufferedImage image, int newSize ) throws Exception { int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); int width; int height; if (imageWidth > imageHeight) { width = newSize; height = imageHeight * width / imageWidth; } else { height = newSize; width = height * imageWidth / imageHeight; } BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = resizedImage.createGraphics(); g.drawImage(image, 0, 0, width, height, null); g.dispose(); return resizedImage; } /** * Read an image from a coverage reader. * * @param reader the reader. * @param cols the expected cols. * @param rows the expected rows. * @param w west bound. * @param e east bound. * @param s south bound. * @param n north bound. * @return the image or <code>null</code> if unable to read it. * @throws IOException */ public static BufferedImage imageFromReader( AbstractGridCoverage2DReader reader, int cols, int rows, double w, double e, double s, double n, CoordinateReferenceSystem resampleCrs ) throws IOException { CoordinateReferenceSystem sourceCrs = reader.getCoordinateReferenceSystem(); GeneralParameterValue[] readParams = new GeneralParameterValue[1]; Parameter<GridGeometry2D> readGG = new Parameter<GridGeometry2D>(AbstractGridFormat.READ_GRIDGEOMETRY2D); GridEnvelope2D gridEnvelope = new GridEnvelope2D(0, 0, cols, rows); DirectPosition2D minDp = new DirectPosition2D(sourceCrs, w, s); DirectPosition2D maxDp = new DirectPosition2D(sourceCrs, e, n); Envelope env = new Envelope2D(minDp, maxDp); readGG.setValue(new GridGeometry2D(gridEnvelope, env)); readParams[0] = readGG; GridCoverage2D gridCoverage2D = reader.read(readParams); if (gridCoverage2D == null) { return null; } if (resampleCrs != null) { gridCoverage2D = (GridCoverage2D) Operations.DEFAULT.resample(gridCoverage2D, resampleCrs); } RenderedImage image = gridCoverage2D.getRenderedImage(); if (image instanceof BufferedImage) { BufferedImage bImage = (BufferedImage) image; return bImage; } else { ColorModel cm = image.getColorModel(); int width = image.getWidth(); int height = image.getHeight(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); Hashtable properties = new Hashtable(); String[] keys = image.getPropertyNames(); if (keys != null) { for( int i = 0; i < keys.length; i++ ) { properties.put(keys[i], image.getProperty(keys[i])); } } BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties); image.copyData(raster); return result; } } /** * Make a color of the image transparent. * * @param bufferedImageToProcess the image to extract the color from. * @param colorToMakeTransparent the color to make transparent. * @return the new image. */ public static BufferedImage makeColorTransparent( BufferedImage bufferedImageToProcess, final Color colorToMakeTransparent ) { ImageFilter filter = new RGBImageFilter(){ public int markerRGB = colorToMakeTransparent.getRGB() | 0xFF000000; public final int filterRGB( int x, int y, int rgb ) { if ((rgb | 0xFF000000) == markerRGB) { // Mark the alpha bits as zero - transparent return 0x00FFFFFF & rgb; } else { return rgb; } } }; ImageProducer ip = new FilteredImageSource(bufferedImageToProcess.getSource(), filter); Image image = Toolkit.getDefaultToolkit().createImage(ip); BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = bufferedImage.createGraphics(); g2.drawImage(image, 0, 0, null); g2.dispose(); return bufferedImage; } /** * Checks if an image is all of one color. * * @param image the image to check. * @return <code>true</code> if the image is all of the same color. */ public static boolean isAllOneColor( BufferedImage image ) { int width = image.getWidth(); int height = image.getHeight(); int previousRgb = 0; boolean isFirst = true; for( int x = 0; x < width; x++ ) { for( int y = 0; y < height; y++ ) { int rgb = image.getRGB(x, y); if (isFirst) { isFirst = false; } else { if (rgb != previousRgb) { return false; } } previousRgb = rgb; } } return true; } }