imageutil.java

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

JAVA
1,510
字号
                double distFromCornerY = srcTop - TM.getNorthing();                long rx = Math.round(distFromCornerX / Math.abs(xPixelSize));                long ry = Math.round(distFromCornerY / Math.abs(yPixelSize));                if (mode == ImageUtil.BILINEAR_INTERPOLATION)                {                    double rxD = distFromCornerX / Math.abs(xPixelSize);                    double ryD = distFromCornerY / Math.abs(yPixelSize);                    int iX = (int) Math.floor(rxD);                    int iY = (int) Math.floor(ryD);                    double dx = rxD - iX;                    double dy = ryD - iY;                    if ((iX > 0) && (iY > 0))                        if ((iX < width - 1) && (iY < height - 1))                        {                            //get four pixels from image                            int a = image.getRGB(iX, iY);                            int b = image.getRGB(iX + 1, iY);                            int c = image.getRGB(iX, iY + 1);                            int d = image.getRGB(iX + 1, iY + 1);                            int sum = interpolateColor(dx, dy, a, b, c, d);                            biOut.setRGB(x, y, Math.round(sum));                        }                        else                            biOut.setRGB(x, y, 0);                }                else  //NEAREST_NEIGHBOR is default                {                    if ((rx > 0) && (ry > 0))                        if ((rx < width) && (ry < height))                            biOut.setRGB(x, y, image.getRGB(Long.valueOf(rx).intValue(), Long.valueOf(ry).intValue()));                        else                            biOut.setRGB(x, y, 0);                }            }        }        values.setValue(AVKey.IMAGE, biOut);    }    /**     * Performs bilinear interpolation of 32-bit colors over a convex quadrilateral. The four colors are specified in     * counterclockwise order beginning with the lower left.     *     * @param x  horizontal coordinate of the interpolation point relative to the lower left corner of the     *           quadrilateral. The value should generally be in the range [0, 1].     * @param y  vertical coordinate of the interpolation point relative to the lower left corner of the quadrilateral.     *           The value should generally be in the range [0, 1].     * @param c0 color at the lower left corner of the quadrilateral.     * @param c1 color at the lower right corner of the quadrilateral.     * @param c2 color at the pixel upper right corner of the quadrilateral.     * @param c3 color at the pixel upper left corner of the quadrilateral.     *     * @return int the interpolated color.     */    public static int interpolateColor(double x, double y, int c0, int c1, int c2, int c3)    {        //pull out alpha, red, green, blue values for each pixel        int a0 = (c0 >> 24) & 0xff;        int r0 = (c0 >> 16) & 0xff;        int g0 = (c0 >> 8) & 0xff;        int b0 = c0 & 0xff;        int a1 = (c1 >> 24) & 0xff;        int r1 = (c1 >> 16) & 0xff;        int g1 = (c1 >> 8) & 0xff;        int b1 = c1 & 0xff;        int a2 = (c2 >> 24) & 0xff;        int r2 = (c2 >> 16) & 0xff;        int g2 = (c2 >> 8) & 0xff;        int b2 = c2 & 0xff;        int a3 = (c3 >> 24) & 0xff;        int r3 = (c3 >> 16) & 0xff;        int g3 = (c3 >> 8) & 0xff;        int b3 = c3 & 0xff;        double rx = 1.0d - x;        double ry = 1.0d - y;        double x0 = rx * a0 + x * a1;        double x1 = rx * a2 + x * a3;        int a = (int) (ry * x0 + y * x1);  //final alpha value        a = a << 24;        x0 = rx * r0 + x * r1;        x1 = rx * r2 + x * r3;        int r = (int) (ry * x0 + y * x1); //final red value        r = r << 16;        x0 = rx * g0 + x * g1;        x1 = rx * g2 + x * g3;        int g = (int) (ry * x0 + y * x1); //final green value        g = g << 8;        x0 = rx * b0 + x * b1;        x1 = rx * b2 + x * b3;        int b = (int) (ry * x0 + y * x1); //final blue value        return (a | r | g | b);    }    public static class AlignedImage    {        public final Sector sector;        public final BufferedImage image;        public AlignedImage(BufferedImage image, Sector sector)        {            this.image = image;            this.sector = sector;        }    }    /**     * Reprojects an image into an aligned image, one with edges of constant latitude and longitude.     *     * @param sourceImage the image to reproject, typically a non-aligned image     * @param latitudes   an array identifying the latitude of each pixels if the source image. There must be an entry     *                    in the array for all pixels. The values are taken to be in row-major order relative to the     *                    image -- the horizontal component varies fastest.     * @param longitudes  an array identifying the longitude of each pixels if the source image. There must be an entry     *                    in the array for all pixels. The values are taken to be in row-major order relative to the     *                    image -- the horizontal component varies fastest.     *     * @return a new image containing the original image but reprojected to align to the bounding sector. Pixels in the     *         new image that have no correspondence with the source image are transparent.     */    public static AlignedImage alignImage(BufferedImage sourceImage, float[] latitudes, float[] longitudes)    {        return alignImage(sourceImage, latitudes, longitudes, null);    }    /**     * Reprojects an image into an aligned image, one with edges of constant latitude and longitude.     *     * @param sourceImage the image to reproject, typically a non-aligned image     * @param latitudes   an array identifying the latitude of each pixels if the source image. There must be an entry     *                    in the array for all pixels. The values are taken to be in row-major order relative to the     *                    image -- the horizontal component varies fastest.     * @param longitudes  an array identifying the longitude of each pixels if the source image. There must be an entry     *                    in the array for all pixels. The values are taken to be in row-major order relative to the     *                    image -- the horizontal component varies fastest.     * @param sector      the sector to align the image to.     *     * @return a new image containing the original image but reprojected to align to the sector. Pixels in the new image     *         that have no correspondence with the source image are transparent.     */    public static AlignedImage alignImage(BufferedImage sourceImage, float[] latitudes, float[] longitudes,        Sector sector)    {        if (sourceImage == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalStateException(message);        }        if (latitudes == null || longitudes == null || latitudes.length != longitudes.length)        {            String message = Logging.getMessage("ImageUtil.FieldArrayInvalid");            Logging.logger().severe(message);            throw new IllegalStateException(message);        }        int width = sourceImage.getWidth();        int height = sourceImage.getHeight();        if (width < 1 || height < 1)        {            String message = Logging.getMessage("ImageUtil.EmptyImage");            Logging.logger().severe(message);            throw new IllegalStateException(message);        }        if (longitudes.length < width * height || latitudes.length < width * height)        {            String message = Logging.getMessage("ImageUtil.FieldArrayTooShort");            Logging.logger().severe(message);            throw new IllegalStateException(message);        }        if (sector == null)            sector = computeExtremes(latitudes, longitudes);        int[] sourceColors = sourceImage.getRGB(0, 0, width, height, null, 0, width);        int[] destColors = new int[sourceColors.length];        ImageInterpolator grid = new ImageInterpolator(new Dimension(width, height), longitudes, latitudes, 10, 1);        double dx = sector.getDeltaLonDegrees() / (width - 1);        double dy = sector.getDeltaLatDegrees() / (height - 1);        for (int j = 0; j < height; j++)        {            float lat = (float) (sector.getMaxLatitude().degrees - j * dy);            for (int i = 0; i < width; i++)            {                float lon = (float) (sector.getMinLongitude().degrees + i * dx);                ImageInterpolator.ContainingCell cell = grid.findContainingCell(lon, lat);                if (cell == null) // no source cell for this lat/lon                {                    destColors[j * width + i] = 0; // transparent                }                else                {                    int color = interpolateColor(cell.uv[0], cell.uv[1],                        sourceColors[cell.fieldIndices[0]],                        sourceColors[cell.fieldIndices[1]],                        sourceColors[cell.fieldIndices[3]],                        sourceColors[cell.fieldIndices[2]]                    );                    destColors[j * width + i] = color;                }            }        }        // Release memory used by source colors and the grid        //noinspection UnusedAssignment        sourceColors = null;        //noinspection UnusedAssignment        grid = null;        BufferedImage destImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);        destImage.setRGB(0, 0, width, height, destColors, 0, width);        return new AlignedImage(destImage, sector);    }    private static Sector computeExtremes(float[] latitudes, float[] longitudes)    {        float minx = Float.MAX_VALUE;        float maxx = -Float.MAX_VALUE;        float miny = Float.MAX_VALUE;        float maxy = -Float.MAX_VALUE;        for (float x : longitudes)        {            if (x < minx)                minx = x;            if (x > maxx)                maxx = x;        }        for (float y : latitudes)        {            if (y < miny)                miny = y;            if (y > maxy)                maxy = y;        }        return Sector.fromDegrees(miny, maxy, minx, maxx);    }////    public static void main(String[] args)//    {//        // Test alignImage(...)//        try//        {//            BufferedImage sourceImage = ImageIO.read(//                new File("src/images/BMNG_world.topo.bathy.200405.3.2048x1024.jpg"));////            int width = sourceImage.getWidth();//            int height = sourceImage.getHeight();////            float[] xs = new float[width * height];//            float[] ys = new float[xs.length];////            double dx = 360d / (width - 1);//            double dy = 180d / (height - 1);////            for (int j = 0; j < height; j++)//            {//                for (int i = 0; i < width; i++)//                {//                    xs[j * width + i] = -180 + i * (float) dx;//                    ys[j * width + i] = -90 + j * (float) dy;//                }//            }//            xs[xs.length - 1] = 180;//            ys[ys.length - 1] = 90;////            long start = System.currentTimeMillis();//            AlignedImage destImage = alignImage(sourceImage, ys, xs, Sector.fromDegrees(-90, 90, -180, 180));////            System.out.println(System.currentTimeMillis() - start);////            int[] src = sourceImage.getRGB(0, 0, width, height, null, 0, width);////            int[] dest = destImage.image.getRGB(0, 0, width, height, null, 0, width);////////            ColorModel cm = destImage.getColorModel();////            double count = 0;////            for (int i = 0; i < src.length; i++)////            {////                if (src[i] != dest[i])////      

⌨️ 快捷键说明

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