imageutil.java

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

JAVA
1,510
字号
    private static long computeSizeOfBufferDataType(int bufferDataType)    {        switch (bufferDataType)        {            case java.awt.image.DataBuffer.TYPE_BYTE:                return (Byte.SIZE / 8);            case java.awt.image.DataBuffer.TYPE_DOUBLE:                return (Double.SIZE / 8);            case java.awt.image.DataBuffer.TYPE_FLOAT:                return (Float.SIZE / 8);            case java.awt.image.DataBuffer.TYPE_INT:                return (Integer.SIZE / 8);            case java.awt.image.DataBuffer.TYPE_SHORT:            case java.awt.image.DataBuffer.TYPE_USHORT:                return (Short.SIZE / 8);            case java.awt.image.DataBuffer.TYPE_UNDEFINED:                break;        }        return 0L;    }    /**     * Opens a spatial image.  Reprojects the image if it is in UTM projection.     *     * @param imageFile          source image     * @param interpolation_mode the interpolation mode if the image is reprojected.     *     * @return AVList     *     * @throws IOException        if there is a problem opening the file.     * @throws WWRuntimeException if the image type is unsupported.     */    public static AVList openSpatialImage(File imageFile, int interpolation_mode) throws IOException // TODO: rename    {        AVList values = new AVListImpl();        BufferedImage image;        Sector sector;        //Check for Geotiff        if ((imageFile.getName().toLowerCase().endsWith(".tiff") || (imageFile.getName().toLowerCase().endsWith(            ".tif"))))        {            GeotiffReader reader = new GeotiffReader(imageFile);            image = reader.read();            if (reader.isGeotiff())            {                return handleGeotiff(image, reader, interpolation_mode);            }        }        //if not geotiff, contine through for other formats        image = ImageIO.read(imageFile);        if (image == null)        {            String message = Logging.getMessage("generic.ImageReadFailed", imageFile);            Logging.logger().severe(message);            throw new WWRuntimeException(message);        }        File[] worldFiles = WorldFile.getWorldFiles(imageFile.getAbsoluteFile());        if (worldFiles == null || worldFiles.length == 0)        {            String message = Logging.getMessage("WorldFile.WorldFileNotFound", imageFile.getAbsolutePath());            Logging.logger().severe(message);            throw new FileNotFoundException(message);        }        values.setValue(AVKey.IMAGE, image);        WorldFile.decodeWorldFiles(worldFiles, values);        sector = (Sector) values.getValue(AVKey.SECTOR);        if (sector == null)            ImageUtil.reprojectUtmToGeographic(values, interpolation_mode);        sector = (Sector) values.getValue(AVKey.SECTOR);        if (sector == null)        {            String message = "Problem generating bounding sector for the image";            throw new WWRuntimeException(message);        }        values.setValue(AVKey.SECTOR, sector);        return values;    }    /**     * Opens a spatial image.  Reprojects the image if it is in UTM projection.     *     * @param imageFile source image     *     * @return AVList     *     * @throws IOException if there is a problem opening the file.     */    public static AVList openSpatialImage(File imageFile) throws IOException    {        return openSpatialImage(imageFile, ImageUtil.NEAREST_NEIGHBOR_INTERPOLATION);    }    /**     * Opens a Geotiff image image.  Reprojects the image if it is in UTM projection.     *     * @param image              BufferedImage     * @param reader             GeotiffReader     * @param interpolation_mode the interpolation mode if the image is reprojected.     *     * @return AVList     *     * @throws IOException if there is a problem opening the file.     */    private static AVList handleGeotiff(BufferedImage image, GeotiffReader reader, int interpolation_mode)        throws IOException    {        AVList values = new AVListImpl();        values.setValue(AVKey.IMAGE, image);        Sector sector;        if ((reader.getGeoCodec().hasGeoKey(GeoCodec.ProjectionGeoKey) || (reader.getGeoCodec().hasGeoKey(            GeoCodec.ProjectedCSTypeGeoKey))))        {            char hemi;            int zone;            int[] vals;            if (reader.getGeoCodec().hasGeoKey(GeoCodec.ProjectionGeoKey))                vals = reader.getGeoCodec().getGeoKeyAsInts(GeoCodec.ProjectionGeoKey);            else                vals = reader.getGeoCodec().getGeoKeyAsInts(GeoCodec.ProjectedCSTypeGeoKey);            int projection = vals[0];            /*            from http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.3.3.2            UTM (North)	Format:  160zz            UTM (South)	Format:  161zz            */            if ((projection >= 16100) && (projection <= 16199))  //UTM Zone South            {                hemi = 'S';                zone = projection - 16100;            }            else if ((projection >= 16000) && (projection <= 16099))  //UTM Zone North            {                hemi = 'N';                zone = projection - 16000;            }            else if ((projection >= 26900) && (projection <= 26999))     //UTM : NAD83            {                hemi = 'N';                zone = projection - 26900;            }            else if ((projection >= 32600) && (projection <= 32699))     //UTM : WGS84            {                hemi = 'N';                zone = projection - 32600;            }            else if ((projection >= 32700) && (projection <= 32799))     //UTM : WGS84            {                hemi = 'S';                zone = projection - 32700;            }            else            {                String message = Logging.getMessage("generic.ProjectionUnsupported");                Logging.logger().severe(message);                throw new IOException(message);            }            //dump "world file" values into values            values.setValue(WorldFile.WORLD_FILE_HEMISPHERE, String.valueOf(hemi));            values.setValue(WorldFile.WORLD_FILE_ZONE, Integer.toString(zone));            values.setValue(WorldFile.WORLD_FILE_X_PIXEL_SIZE, reader.getGeoCodec().getModelPixelScaleX());            values.setValue(WorldFile.WORLD_FILE_Y_PIXEL_SIZE, (-1 * reader.getGeoCodec().getModelPixelScaleY()));            //shift to center            double xD = reader.getGeoCodec().getTiePoints()[0].getX() + (reader.getGeoCodec().getModelPixelScaleX()                * .5);            double yD = reader.getGeoCodec().getTiePoints()[0].getY() - (reader.getGeoCodec().getModelPixelScaleY()                * .5);            values.setValue(WorldFile.WORLD_FILE_X_LOCATION, xD);            values.setValue(WorldFile.WORLD_FILE_Y_LOCATION, yD);            ImageUtil.reprojectUtmToGeographic(values, interpolation_mode);            sector = (Sector) values.getValue(AVKey.SECTOR);        }        else if (reader.getGeoCodec().hasGeoKey(GeoCodec.GeographicTypeGeoKey) && !reader.getGeoCodec()            .hasGeoKey(GeoCodec.ProjectedCSTypeGeoKey))        {            //assumes GEO    todo check for geo code 4326            double[] bbox = reader.getGeoCodec().getBoundingBox(image.getWidth(), image.getHeight());            sector = new Sector(Angle.fromDegreesLatitude(bbox[3]), Angle.fromDegreesLatitude(bbox[1]),                Angle.fromDegreesLongitude(bbox[0]), Angle.fromDegreesLongitude(bbox[2]));        }        else        {            String message = Logging.getMessage("generic.ProjectionUnsupported");            Logging.logger().severe(message);            throw new IOException(message);        }        values.setValue(AVKey.SECTOR, sector);        return values;    }    /**     * Reprojects an imge in UTM projection to Geo/WGS84.     *     * @param values AVList: contains the bufferedimage and the values from the world file. Stores resulting image in     *               values     * @param mode   the interpolation mode if the image is reprojected.     */    public static void reprojectUtmToGeographic(AVList values, int mode)    {        //TODO pull these const from TMCoord?        double False_Easting = 500000;        double False_Northing = 0;        double Scale = 0.9996;        Earth earth = new Earth(); //need globe for TM        if (values == null)        {            String message = Logging.getMessage("nullValue.ImageSource"); // TODO: correct log message            Logging.logger().severe(message);            throw new IllegalStateException(message);        }        BufferedImage image = (BufferedImage) values.getValue(AVKey.IMAGE);        int width = image.getWidth();        int height = image.getHeight();        BufferedImage biOut;        //Note: image type always BufferedImage.TYPE_INT_ARGB to handle transparent no-data areas after reprojection        if ((image.getColorModel() != null) && (image.getColorModel() instanceof IndexColorModel))        {            biOut = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB,                (IndexColorModel) image.getColorModel());        }        else        {            biOut = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);        }        double xPixelSize = 0;        double yPixelSize = 0;        Object o = values.getValue(WorldFile.WORLD_FILE_X_PIXEL_SIZE);        if (o != null && o instanceof Double)            xPixelSize = (Double) o;        o = values.getValue(WorldFile.WORLD_FILE_Y_PIXEL_SIZE);        if (o != null && o instanceof Double)            yPixelSize = (Double) o;        // TODO: validate that all these values exist and are valid        double xLocation = (Double) values.getValue(WorldFile.WORLD_FILE_X_LOCATION);        double yLocation = (Double) values.getValue(WorldFile.WORLD_FILE_Y_LOCATION);        int zone = Integer.parseInt((String) values.getValue(WorldFile.WORLD_FILE_ZONE));        char hemisphere = ((String) values.getValue(WorldFile.WORLD_FILE_HEMISPHERE)).charAt(0);        UTMCoord upperLeft = UTMCoord.fromUTM(zone, hemisphere, xLocation, yLocation);        UTMCoord utmUpperLeft = UTMCoord.fromUTM(zone, hemisphere, upperLeft.getEasting() - xPixelSize * .5,            upperLeft.getNorthing() - yPixelSize * .5);        UTMCoord utmLowerRight = UTMCoord.fromUTM(zone, hemisphere, utmUpperLeft.getEasting() + (width * xPixelSize),            utmUpperLeft.getNorthing() + (height * yPixelSize));        //Get rect Geo bbox        UTMCoord utmLowerLeft = UTMCoord.fromUTM(zone, upperLeft.getHemisphere(), utmUpperLeft.getEasting(),            utmLowerRight.getNorthing());        UTMCoord utmUpperRight = UTMCoord.fromUTM(zone, upperLeft.getHemisphere(), utmLowerRight.getEasting(),            utmUpperLeft.getNorthing());        Angle rightExtent = Angle.max(utmUpperRight.getLongitude(), utmLowerRight.getLongitude());        Angle leftExtent = Angle.min(utmLowerLeft.getLongitude(), utmUpperLeft.getLongitude());        Angle topExtent = Angle.max(utmUpperRight.getLatitude(), utmUpperLeft.getLatitude());        Angle bottomExtent = Angle.min(utmLowerRight.getLatitude(), utmLowerLeft.getLatitude());        Sector sector = new Sector(bottomExtent, topExtent, leftExtent, rightExtent);        values.setValue(AVKey.SECTOR, sector);        //moving to center of pixel        double yPixel = (bottomExtent.getDegrees() - topExtent.getDegrees()) / height;        double xPixel = (rightExtent.getDegrees() - leftExtent.getDegrees()) / width;        double topExtent2 = sector.getMaxLatitude().getDegrees() + (yPixel * .5);        double leftExtent2 = sector.getMinLongitude().getDegrees() + (xPixel * .5);        TMCoord tmUpperLeft = TMCoord.fromLatLon(utmUpperLeft.getLatitude(), utmUpperLeft.getLongitude(),            earth, Angle.fromDegrees(0.0), utmUpperLeft.getCentralMeridian(),            False_Easting, False_Northing, Scale);        double srcTop = tmUpperLeft.getNorthing() + (yPixelSize * .5);        double srcLeft = tmUpperLeft.getEasting() + (xPixelSize * .5);        for (int y = 0; y < height; y++)        {            for (int x = 0; x < width; x++)            {                double yTarget = topExtent2 + y * yPixel;                double xTarget = leftExtent2 + x * xPixel;                TMCoord TM = TMCoord.fromLatLon(Angle.fromDegreesLatitude(yTarget), Angle.fromDegreesLongitude(xTarget),                    earth, Angle.fromDegrees(0.0), utmUpperLeft.getCentralMeridian(),                    False_Easting, False_Northing, Scale);                double distFromCornerX = TM.getEasting() - srcLeft;

⌨️ 快捷键说明

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