imageutil.java

来自「world wind java sdk 源码」· Java 代码 · 共 1,510 行 · 第 1/5 页

JAVA
1,510
字号
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.util;import gov.nasa.worldwind.avlist.*;import gov.nasa.worldwind.exception.WWRuntimeException;import gov.nasa.worldwind.formats.tiff.*;import gov.nasa.worldwind.formats.worldfile.WorldFile;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.geom.coords.*;import gov.nasa.worldwind.globes.Earth;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.*;import java.io.*;import java.util.*;import java.util.List;/** * @author tag * @version $Id: ImageUtil.java 9716 2009-03-27 16:55:14Z dcollins $ */public class ImageUtil{    public static int NEAREST_NEIGHBOR_INTERPOLATION = 1;    public static int BILINEAR_INTERPOLATION = 2;    public static int IMAGE_TILE_SIZE = 1024; // default size to make subimages    public static Color TRANSPARENT = new Color(0, 0, 0, 0);    /**     * Draws the specified <code>image</code> onto the <code>canvas</code>, scaling or streching the image to fit the     * canvas. This will apply a bilinear filter to the image if any scaling or streching is necessary.     *     * @param image  the BufferedImage to draw, potentially scaling or streching to fit the <code>canvas</code>.     * @param canvas the BufferedImage to receive the scaled or streched <code>image</code>.     *     * @throws IllegalArgumentException if either <code>image</code> or <code>canvas</code> is null.     */    public static void drawImageOnCanvas(BufferedImage image, BufferedImage canvas) // TODO: rename    {        if (image == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (canvas == null)        {            String message = Logging.getMessage("nullValue.CanvasIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        java.awt.Graphics2D g2d = canvas.createGraphics();        try        {            g2d.setComposite(java.awt.AlphaComposite.Src);            g2d.setRenderingHint(                java.awt.RenderingHints.KEY_INTERPOLATION, java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR);            g2d.drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight(), null);        }        finally        {            g2d.dispose();        }    }    /**     * Rasterizes the image into the canvas, given a transform that maps canvas coordinates to image coordinates.     *     * @param image                  the source image.     * @param canvas                 the image to receive the transformed source image.     * @param canvasToImageTransform <code>Matrix</code> that maps a canvas coordinates to image coordinates.     *     * @throws IllegalArgumentException if any of <code>image</code>, <code>canvas</code>, or <code>canvasToImageTransform</code>     *                                  are null.     */    public static void warpImageWithTransform(BufferedImage image, BufferedImage canvas, Matrix canvasToImageTransform)    {        if (image == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (canvas == null)        {            String message = Logging.getMessage("nullValue.CanvasIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (canvasToImageTransform == null)        {            String message = Logging.getMessage("nullValue.MatrixIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        int sourceWidth = image.getWidth();        int sourceHeight = image.getHeight();        int destWidth = canvas.getWidth();        int destHeight = canvas.getHeight();        for (int dy = 0; dy < destHeight; dy++)        {            for (int dx = 0; dx < destWidth; dx++)            {                Vec4 vec = new Vec4(dx, dy, 1).transformBy3(canvasToImageTransform);                if (vec.x >= 0 && vec.y >= 0 && vec.x <= (sourceWidth - 1) && vec.y <= (sourceHeight - 1))                {                    int x0 = (int) Math.floor(vec.x);                    int x1 = (int) Math.ceil(vec.x);                    double xf = vec.x - x0;                    int y0 = (int) Math.floor(vec.y);                    int y1 = (int) Math.ceil(vec.y);                    double yf = vec.y - y0;                    int color = interpolateColor(xf, yf,                        image.getRGB(x0, y0),                        image.getRGB(x1, y0),                        image.getRGB(x0, y1),                        image.getRGB(x1, y1));                    canvas.setRGB(dx, dy, color);                }            }        }    }    /**     * Convenience method for transforming a georeferenced source image into a geographically aligned destination image.     * The source image is georeferenced by either three four control points. Each control point maps a location in the     * source image to a geographic location. This is equivalent to calling {#transformConstrainedImage3} or     * {#transformConstrainedImage4}, depending on the number of control points.     *     * @param sourceImage the source image to transform.     * @param imagePoints three or four control points in the source image.     * @param geoPoints   three or four geographic locations corresponding to each source control point.     * @param destImage   the destination image to receive the transformed source imnage.     *     * @return bounding sector for the geographically aligned destination image.     *     * @throws IllegalArgumentException if any of <code>sourceImage</code>, <code>destImage</code>,     *                                  <code>imagePoints</code> or <code>geoPoints</code> is null, or if either     *                                  <code>imagePoints</code> or <code>geoPoints</code> have length less than 3.     */    public static Sector warpImageWithControlPoints(BufferedImage sourceImage, java.awt.geom.Point2D[] imagePoints,        LatLon[] geoPoints, BufferedImage destImage)    {        if (sourceImage == null)        {            String message = Logging.getMessage("nullValue.SourceImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (destImage == null)        {            String message = Logging.getMessage("nullValue.DestinationImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        String message = validateControlPoints(3, imagePoints, geoPoints);        if (message != null)        {            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (imagePoints.length >= 4 && geoPoints.length >= 4)        {            return warpImageWithControlPoints4(sourceImage, imagePoints, geoPoints, destImage);        }        else // (imagePoints.length == 3)        {            return warpImageWithControlPoints3(sourceImage, imagePoints, geoPoints, destImage);        }    }    /**     * Transforms a georeferenced source image into a geographically aligned destination image. The source image is     * georeferenced by four control points. Each control point maps a location in the source image to a geographic     * location.     *     * @param sourceImage the source image to transform.     * @param imagePoints four control points in the source image.     * @param geoPoints   four geographic locations corresponding to each source control point.     * @param destImage   the destination image to receive the transformed source imnage.     *     * @return bounding sector for the geographically aligned destination image.     * @throws IllegalArgumentException if any of <code>sourceImage</code>, <code>destImage</code>,     *                                  <code>imagePoints</code> or <code>geoPoints</code> is null, or if either     *                                  <code>imagePoints</code> or <code>geoPoints</code> have length less than 4.     */    public static Sector warpImageWithControlPoints4(BufferedImage sourceImage, java.awt.geom.Point2D[] imagePoints,        LatLon[] geoPoints, BufferedImage destImage)    {        if (sourceImage == null)        {            String message = Logging.getMessage("nullValue.SourceImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (destImage == null)        {            String message = Logging.getMessage("nullValue.DestinationImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        String message = validateControlPoints(4, imagePoints, geoPoints);        if (message != null)        {            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        // We can only create an affine transform from three of the given points. To increase accruacy, we will compute        // the error for each combination of three points, and choose the combination with the least error.        java.awt.geom.Point2D[] bestFitImagePoints = new java.awt.geom.Point2D[3];        LatLon[] bestFitGeoPoints = new LatLon[3];        computeBestFittingControlPoints4(imagePoints, geoPoints, bestFitImagePoints, bestFitGeoPoints);        return warpImageWithControlPoints3(sourceImage, bestFitImagePoints, bestFitGeoPoints, destImage);    }    /**     * Transforms a georeferenced source image into a geographically aligned destination image. The source image is     * georeferenced by three control points. Each control point maps a location in the source image to a geographic     * location.     *     * @param sourceImage the source image to transform.     * @param imagePoints three control points in the source image.     * @param geoPoints three geographic locations corresponding to each source control point.     * @param destImage the destination image to receive the transformed source imnage.     *     * @return bounding sector for the geographically aligned destination image.     *     * @throws IllegalArgumentException if any of <code>sourceImage</code>, <code>destImage</code>,     *                                  <code>imagePoints</code> or <code>geoPoints</code> is null, or if either     *                                  <code>imagePoints</code> or <code>geoPoints</code> have length less than 3.     */    public static Sector warpImageWithControlPoints3(BufferedImage sourceImage, java.awt.geom.Point2D[] imagePoints,        LatLon[] geoPoints, BufferedImage destImage)    {        if (sourceImage == null)        {            String message = Logging.getMessage("nullValue.SourceImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (destImage == null)        {            String message = Logging.getMessage("nullValue.DestinationImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        String message = validateControlPoints(3, imagePoints, geoPoints);        if (message != null)        {            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        // Compute the destination sector. We want a lat/lon aligned sector that bounds the source image once it is        // transformed into a lat/lon aligned image. We compute a matrix that will map source grid coordinates to        // geographic coordinates. Then we transform the source image's four corners into geographic coordinates.        // The sector we want is the sector that bounds those four geographic coordinates.        Matrix gridToGeographic = Matrix.fromImageToGeographic(imagePoints, geoPoints);        List<LatLon> corners = computeImageCorners(sourceImage.getWidth(), sourceImage.getHeight(), gridToGeographic);        Sector destSector = Sector.boundingSector(corners);        if (Sector.isSector(corners) && destSector.isSameSector(corners))        {            drawImageOnCanvas(sourceImage, destImage);        }        else        {            // Compute a matrix that will map from destination grid coordinates to source grid coordinates. By using            // matrix multiplication in this order, an incoming vector will be transformed by the last matrix multiplied,            // then the previous, and so on. So an incoming destination coordinate would be transformed into geographic            // coordinates, then into source coordinates.            Matrix transform = Matrix.IDENTITY;            transform = transform.multiply(Matrix.fromGeographicToImage(imagePoints, geoPoints));            transform = transform.multiply(Matrix.fromImageToGeographic(destImage.getWidth(), destImage.getHeight(),                destSector));            warpImageWithTransform(sourceImage, destImage, transform);        }        return destSector;    }    /**     * Transforms a georeferenced source image into a geographically aligned destination image. The source image is     * georeferenced by a world file, which defines an affine transform from source coordinates to geographic

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?