Commit f952aeb7 authored by Matija Obreza's avatar Matija Obreza
Browse files

Added support for tile coloring in 0xRRGGBB color notation

parent 6e91c2cd
/*
Copyright 2006 Jerry Huxtable
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 com.jhlabs.image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorModel;
/**
* A convenience class which implements those methods of BufferedImageOp which
* are rarely changed.
*/
public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
if (dstCM == null)
dstCM = src.getColorModel();
return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
}
public Rectangle2D getBounds2D(BufferedImage src) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
if (dstPt == null)
dstPt = new Point2D.Double();
dstPt.setLocation(srcPt.getX(), srcPt.getY());
return dstPt;
}
public RenderingHints getRenderingHints() {
return null;
}
/**
* A convenience method for getting ARGB pixels from an image. This tries to
* avoid the performance penalty of BufferedImage.getRGB unmanaging the
* image.
*
* @param image
* a BufferedImage object
* @param x
* the left edge of the pixel block
* @param y
* the right edge of the pixel block
* @param width
* the width of the pixel arry
* @param height
* the height of the pixel arry
* @param pixels
* the array to hold the returned pixels. May be null.
* @return the pixels
* @see #setRGB
*/
public int[] getRGB(BufferedImage image, int x, int y, int width, int height, int[] pixels) {
int type = image.getType();
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB)
return (int[]) image.getRaster().getDataElements(x, y, width, height, pixels);
return image.getRGB(x, y, width, height, pixels, 0, width);
}
/**
* A convenience method for setting ARGB pixels in an image. This tries to
* avoid the performance penalty of BufferedImage.setRGB unmanaging the
* image.
*
* @param image
* a BufferedImage object
* @param x
* the left edge of the pixel block
* @param y
* the right edge of the pixel block
* @param width
* the width of the pixel arry
* @param height
* the height of the pixel arry
* @param pixels
* the array of pixels to set
* @see #getRGB
*/
public void setRGB(BufferedImage image, int x, int y, int width, int height, int[] pixels) {
int type = image.getType();
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB)
image.getRaster().setDataElements(x, y, width, height, pixels);
else
image.setRGB(x, y, width, height, pixels, 0, width);
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
/*
Copyright 2006 Jerry Huxtable
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 com.jhlabs.image;
/**
* A filter which replaces one color by another in an image. This is frankly,
* not often useful, but has its occasional uses when dealing with GIF
* transparency and the like.
*/
public class MapColorsFilter extends PointFilter {
private int oldColor;
private int newColor;
/**
* Construct a MapColorsFilter.
*/
public MapColorsFilter() {
this(0xffffffff, 0xff000000);
}
/**
* Construct a MapColorsFilter.
*
* @param oldColor
* the color to replace
* @param newColor
* the color to replace it with
*/
public MapColorsFilter(int oldColor, int newColor) {
canFilterIndexColorModel = true;
this.oldColor = oldColor;
this.newColor = newColor;
}
public int filterRGB(int x, int y, int rgb) {
if (rgb == oldColor)
return newColor;
return rgb;
}
}
/*
Copyright 2006 Jerry Huxtable
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 com.jhlabs.image;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
/**
* An abstract superclass for point filters. The interface is the same as the
* old RGBImageFilter.
*/
public abstract class PointFilter extends AbstractBufferedImageOp {
protected boolean canFilterIndexColorModel = false;
public BufferedImage filter(BufferedImage src, BufferedImage dst) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if (dst == null)
dst = createCompatibleDestImage(src, null);
WritableRaster dstRaster = dst.getRaster();
setDimensions(width, height);
int[] inPixels = new int[width];
for (int y = 0; y < height; y++) {
// We try to avoid calling getRGB on images as it causes them to
// become unmanaged, causing horrible performance problems.
if (type == BufferedImage.TYPE_INT_ARGB) {
srcRaster.getDataElements(0, y, width, 1, inPixels);
for (int x = 0; x < width; x++)
inPixels[x] = filterRGB(x, y, inPixels[x]);
dstRaster.setDataElements(0, y, width, 1, inPixels);
} else {
src.getRGB(0, y, width, 1, inPixels, 0, width);
for (int x = 0; x < width; x++)
inPixels[x] = filterRGB(x, y, inPixels[x]);
dst.setRGB(0, y, width, 1, inPixels, 0, width);
}
}
return dst;
}
public void setDimensions(int width, int height) {
}
public abstract int filterRGB(int x, int y, int rgb);
}
......@@ -160,7 +160,6 @@ public class MappingServiceImpl implements MappingService {
LOG.warn("Cleared tiles cache");
}
// TODO Add caching
@Override
@Cacheable(value = "tileserver", key = "'tile-' + #zoom + '-' + #xtile + '-' + #ytile + '-' + #jsonFilter")
public byte[] getTile(String jsonFilter, final int zoom, final int xtile, final int ytile) {
......
......@@ -16,11 +16,16 @@
package org.genesys2.server.servlet.controller;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
......@@ -56,6 +61,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jhlabs.image.MapColorsFilter;
@Controller
public class ExplorerController extends BaseController {
......@@ -304,17 +310,57 @@ public class ExplorerController extends BaseController {
}
@RequestMapping(value = "/explore/tile/{zoom}/{x}/{y}", produces = MediaType.IMAGE_PNG_VALUE)
@ResponseBody
public byte[] tile(@RequestParam(value = "filter", required = true) String jsonFilter, @PathVariable("zoom") int zoom, @PathVariable("x") int x,
@PathVariable("y") int y) {
public void tile(@RequestParam(value = "filter", required = true) String jsonFilter, @PathVariable("zoom") int zoom, @PathVariable("x") int x,
@PathVariable("y") int y, @RequestParam(value = "color", required = false) String color, HttpServletResponse response) {
try {
return mappingService.getTile(jsonFilter, zoom, x, y);
byte[] image = mappingService.getTile(jsonFilter, zoom, x, y);
image = changeColor(color, image);
response.getOutputStream().write(image, 0, image.length);
} catch (IOException e) {
_logger.warn(e.getMessage());
throw new RuntimeException("Could not render image", e);
} catch (Throwable e) {
_logger.error(e.getMessage(), e);
throw new ResourceNotFoundException(e.getMessage());
}
}
/**
* Change color of the tile
*
* @param color
* @param imageBytes
* @return
*/
private byte[] changeColor(String color, byte[] imageBytes) {
if (color == null)
return imageBytes;
_logger.info("Changing color to " + color);
try {
Color newColor = Color.decode(color);
if (newColor.equals(Color.yellow))
return imageBytes;
MapColorsFilter mcf = new MapColorsFilter(Color.yellow.getRGB(), newColor.getRGB());
ByteArrayInputStream bios=new ByteArrayInputStream(imageBytes);
BufferedImage image = mcf.filter(ImageIO.read(bios), null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "PNG", baos);
return baos.toByteArray();
} catch (NumberFormatException e) {
_logger.warn("Cannot get color for " + color);
return imageBytes;
} catch (IOException e) {
_logger.warn(e.getMessage());
return imageBytes;
}
}
@RequestMapping(value = "/explore/geoJson", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String geoJson(@RequestParam(value = "crop", required = false, defaultValue = "") String cropName,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment