Java tutorial
/* * polymap.org * Copyright 2009, Polymap GmbH, and individual contributors as indicated * by the @authors tag. * * This 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; either version 2.1 of * the License, or (at your option) any later version. * * This software 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. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * * $Id$ */ package org.polymap.core.data.image; import java.util.Properties; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.polymap.core.data.pipeline.PipelineProcessor; import org.polymap.core.data.pipeline.ProcessorRequest; import org.polymap.core.data.pipeline.ProcessorResponse; import org.polymap.core.data.pipeline.ProcessorSignature; import org.polymap.core.data.pipeline.PipelineExecutor.ProcessorContext; import org.polymap.core.project.LayerUseCase; /** * Process the image of a {@link ImageResponse} into one color to transparent * pixel image. * * @author <a href="http://www.polymap.de">Falko Braeutigam</a> * @version POLYMAP3 ($Revision$) * @since 3.0 */ public class ImageTransparencyProcessor implements PipelineProcessor { private static final Log log = LogFactory.getLog(ImageTransparencyProcessor.class); public static final String PROP_MARKER_COLOR = "markerColor"; private static final ProcessorSignature signature = new ProcessorSignature( new Class[] { GetMapRequest.class, GetLegendGraphicRequest.class, GetLayerTypesRequest.class }, new Class[] { GetMapRequest.class, GetLegendGraphicRequest.class, GetLayerTypesRequest.class }, new Class[] { EncodedImageResponse.class, ImageResponse.class, GetLayerTypesResponse.class }, new Class[] { EncodedImageResponse.class, ImageResponse.class, GetLayerTypesResponse.class }); public static ProcessorSignature signature(LayerUseCase usecase) { return signature; } // instance ******************************************* private Color markerColor; public void init(Properties props) { String color = props.getProperty(PROP_MARKER_COLOR, "ffffff"); markerColor = new Color(Integer.parseInt(color, 16)); log.info("Color: " + markerColor.toString()); } public void processRequest(ProcessorRequest r, ProcessorContext context) throws Exception { // pass through any request context.sendRequest(r); } public void processResponse(ProcessorResponse r, ProcessorContext context) throws Exception { // ImageResponse if (r instanceof ImageResponse) { ImageResponse response = (ImageResponse) r; Image image = response.getImage(); doImageResponse(image, context); } // EncodedImageResponse else if (r instanceof EncodedImageResponse) { doEncodedImageResponse(r, context); } else if (r == ProcessorResponse.EOP && context.get("buf") != null) { doEncodedImageResponse(r, context); } // pass any other response else { context.sendResponse(r); } } private void doEncodedImageResponse(ProcessorResponse r, ProcessorContext context) throws Exception { if (r != ProcessorResponse.EOP) { ByteArrayOutputStream buf = (ByteArrayOutputStream) context.get("buf"); if (buf == null) { buf = new ByteArrayOutputStream(); context.put("buf", buf); } EncodedImageResponse response = (EncodedImageResponse) r; buf.write(response.getChunk(), 0, response.getChunkSize()); } else { ByteArrayOutputStream buf = (ByteArrayOutputStream) context.get("buf"); //Image image = Toolkit.getDefaultToolkit().createImage( buf.toByteArray() ); BufferedImage image = ImageIO.read(new ByteArrayInputStream(buf.toByteArray())); Image result = transparency(image, markerColor); ImageEncodeProcessor encodeProcessor = new ImageEncodeProcessor(); context.put("format", "image/png"); encodeProcessor.doImageResponse(result, context); } } protected void doImageResponse(Image image, final ProcessorContext context) throws Exception { context.sendResponse(new ImageResponse(transparency(image, markerColor))); context.sendResponse(ProcessorResponse.EOP); } public static BufferedImage transparency(Image image, final Color markerColor) throws IOException { long start = System.currentTimeMillis(); RGBImageFilter filter = new RGBImageFilter() { // the color we are looking for... Alpha bits are set to opaque public int markerRGB = markerColor.getRGB() | 0xFF000000; byte threshold = 25; double range = ((double) 0xFF) / (3 * threshold); public final int filterRGB(int x, int y, int rgb) { Color probe = new Color(rgb); //log.info( "probe=" + probe + ", marker=" + markerColor ); // delta values int dRed = markerColor.getRed() - probe.getRed(); int dGreen = markerColor.getGreen() - probe.getGreen(); int dBlue = markerColor.getBlue() - probe.getBlue(); //log.info( " dRed=" + dRed + ", dGreen=" + dGreen ); if (dRed >= 0 && dRed < threshold && dGreen >= 0 && dGreen < threshold && dBlue >= 0 && dBlue < threshold) { int alpha = (int) Math.round(range * (dRed + dGreen + dBlue)); //log.info( " -> alpha=" + alpha ); return ((alpha << 24) | 0x00FFFFFF) & rgb; } else { // nothing to do return rgb; } } }; // BufferedImage bimage = null; // if (image instanceof BufferedImage) { // bimage = (BufferedImage)image; // } // else { // bimage = new BufferedImage( // image.getHeight( null ), image.getWidth( null ), BufferedImage.TYPE_INT_ARGB ); // Graphics g = bimage.getGraphics(); // g.drawImage( image, 0, 0, null ); // g.dispose(); // } ImageProducer ip = new FilteredImageSource(image.getSource(), filter); Image result = Toolkit.getDefaultToolkit().createImage(ip); BufferedImage bresult = new BufferedImage(image.getHeight(null), image.getWidth(null), BufferedImage.TYPE_INT_ARGB); Graphics g = bresult.getGraphics(); g.drawImage(result, 0, 0, null); g.dispose(); // // XXX this can surely be done any more clever // int width = bimage.getWidth(); // int height = bimage.getHeight(); // for (int x=bimage.getMinX(); x<width; x++) { // for (int y=bimage.getMinY(); y<height; y++) { // int filtered = filter.filterRGB( x, y, bimage.getRGB( x, y ) ); // result.setRGB( x, y, filtered ); // } // } log.debug("Transparency done. (" + (System.currentTimeMillis() - start) + "ms)"); return bresult; } // public static Image transparency( Image image, final Color markerColor ) { // long start = System.currentTimeMillis(); // // // load image data // new javax.swing.ImageIcon( image ).getImage(); // // if (!(image instanceof BufferedImage)) { // BufferedImage bimage = new BufferedImage( // image.getHeight( null ), image.getWidth( null ), BufferedImage.TYPE_4BYTE_ABGR ); // Graphics g = bimage.getGraphics(); // g.drawImage( image, 0, 0, null ); // g.dispose(); // // image = bimage; // } // // ImageFilter filter = new RGBImageFilter() { // // the color we are looking for... Alpha bits are set to opaque // public int markerRGB = markerColor.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 { // // nothing to do // return rgb; // } // } // }; // // ImageProducer ip = new FilteredImageSource( image.getSource(), filter ); // Image result = Toolkit.getDefaultToolkit().createImage( ip ); // // BufferedImage bImage = new BufferedImage( // result.getHeight( null ), result.getWidth( null ), BufferedImage.TYPE_4BYTE_ABGR ); // // Graphics g = bImage.getGraphics(); // g.drawImage( result, 0, 0, null ); // g.dispose(); // // log.info( "Transparency done. (" + (System.currentTimeMillis()-start) + "ms)" ); // return bImage; // } }