📄 abstractimageformatter.java
字号:
// **********************************************************************// // <copyright>// // BBN Technologies// 10 Moulton Street// Cambridge, MA 02138// (617) 873-8000// // Copyright (C) BBNT Solutions LLC. All rights reserved.// // </copyright>// **********************************************************************// // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/image/AbstractImageFormatter.java,v $// $RCSfile: AbstractImageFormatter.java,v $// $Revision: 1.5.2.3 $// $Date: 2005/11/23 20:51:02 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.image;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.GraphicsEnvironment;import java.awt.image.BufferedImage;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.util.Properties;import com.bbn.openmap.Layer;import com.bbn.openmap.MapBean;import com.bbn.openmap.PropertyConsumer;import com.bbn.openmap.proj.Proj;import com.bbn.openmap.proj.Projection;import com.bbn.openmap.util.Debug;/** * The abstract implementation of the ImageFormatter. The * ImageFormatter deals with most of the image meanderings of Java, * while letting you create an image in a specific format. The * ImageFormatter's responsibility has grown slightly, since it now * contains the BufferedImage that it will be formatting. Thisis to * make things go smoother for different uses of the formatter - some * image formats, for instance, really need to utilize a special * implementation of a Graphics in order to create the data file they * want. The new definition allows for that. Generally, however, * you'll want to either hand the MapBean to the formatter to get the * image bytes, or, as in the case of the ImageServer, get a Graphics * from the formatter, paint the map into it, then retrieve the image * bytes after that. */public abstract class AbstractImageFormatter implements ImageFormatter, PropertyConsumer, PropertyChangeListener { protected BufferedImage bufferedImage; protected String propertiesPrefix; public AbstractImageFormatter() {} /** Set the properties of the image formatter. */ public void setProperties(String prefix, Properties props) {} /** * Convert a BufferedImage to a image file format... * * @param bi a BufferedImage.. */ public abstract byte[] formatImage(BufferedImage bi); /** * Create a new instance of the same type of formatter. If you are * running in a multi-threaded environment, you'll need to provide * a new instance of the formatter to each thread, since the image * and graphics that are being drawn into for each thread are * contained within. * * @return a new instance of this type of formatter, with the same * properties set. */ public abstract ImageFormatter makeClone(); /** * Take a MapBean, and get the image bytes that represent the * current state. * * @param map the MapBean. * @return byte[] representing an image of the map in it's current * state. */ public byte[] getImageFromMapBean(MapBean map) { return getImageFromMapBean(map, -1, -1, false); } /** * Take a MapBean, and get the image bytes that represent the * current state. * * @param map the MapBean. * @param width the pixel width of the desired image. * @param height the pixel height of the desired image. * @return byte[] representing an image of the map in it's current * state. */ public byte[] getImageFromMapBean(MapBean map, int width, int height) { return getImageFromMapBean(map, width, height, true); } /** * Take a MapBean, and get the image bytes that represent the * current state. * * @param map the MapBean. * @param width the pixel width of the desired image. * @param height the pixel height of the desired image. * @param scaleImage true to resize image based on scale * @return byte[] representing an image of the map in it's current * state. */ public byte[] getImageFromMapBean(MapBean map, int width, int height, boolean scaleImage) { if (map == null) { return new byte[0]; } Proj proj = (Proj) map.getProjection(); boolean needToScale = (width != proj.getWidth() || height != proj.getHeight()); if (Debug.debugging("formatter")) { Debug.output("AIF: called with w:" + width + ", h:" + height + ", need to scale (" + needToScale + ")" + " and scaleImage (" + scaleImage + ")"); } if (width == -1) width = proj.getWidth(); if (height == -1) height = proj.getHeight(); Graphics graphics = getGraphics(width, height); if (!needToScale) { if (Debug.debugging("formatter")) { Debug.output("AIF: don't need to scale, painting normally."); } // This way just paints what the MapBean is displaying. map.paintAll(graphics); } else { // One problem with this approach is that it will // use the ProjectionPainter interface on the layers. So, // you may not get the same image that is on the map. All // layers on the map will get painted in the image - so if // a layer hasn't painted itself on the map window, you // will see it in the image. // This lets us know what the layers are map.addPropertyChangeListener(this); // Layers should be set... com.bbn.openmap.LatLonPoint cp = new com.bbn.openmap.LatLonPoint(map.getCenter()); double scaleMod = 1f;// scale factor for image scale // If we need to scale the image, // figure out the scale factor. if (scaleImage) { if (Debug.debugging("formatter")) { Debug.output("AIF: scaling image to w:" + width + ", h:" + height); } double area1 = (double) proj.getHeight() * (double) proj.getWidth(); double area2 = (double) height * (double) width; scaleMod = Math.sqrt(area1 / area2); } Proj tp = (Proj) com.bbn.openmap.proj.ProjectionFactory.makeProjection(map.getProjection() .getClass(), cp.getLatitude(), cp.getLongitude(), map.getScale() * (float) scaleMod, width, height); tp.drawBackground((Graphics2D) graphics, map.getBckgrnd()); if (layers != null) { for (int i = layers.length - 1; i >= 0; i--) { Projection oldProj = layers[i].getProjection(); layers[i].renderDataForProjection(tp, graphics); if (Debug.debugging("formatter")) { Debug.output("AbstractImageFormatter: rendering " + layers[i].getName()); } // Need to set the old Projection object on the // Layer, not the current MapBean Proj object. If // you set the MapBean Proj object, make sure you // clone it first. The Layer will do a check on // the Projection object it has against any new // ones it receives. If it has the original from // the MapBean, the check it does will return a // false negative, and the layer will think it // doesn't have to do anything. if (oldProj != null && oldProj == map.getProjection()) { // Seems like a lot of users are getting // burned by manually setting the same // projection on the MapBean as they are on // the layers, and the layers are freezing up // after they are used to create an image. // I don't see how this problem is manifesting // itself, but this code section is an attempt // to help. oldProj = oldProj.makeClone(); } layers[i].setProjection(oldProj); } } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -