imageutil.java

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

JAVA
1,510
字号
        bc = sourcePixels.getBarycentricCoords(new Vec4(sourceImage.getWidth(), sourceImage.getHeight(), 0));        extremes.add(sourceLatLon.getLocation(bc));        // Upper right corner.        bc = sourcePixels.getBarycentricCoords(new Vec4(sourceImage.getWidth(), 0, 0));        extremes.add(sourceLatLon.getLocation(bc));        // Upper left corner.        bc = sourcePixels.getBarycentricCoords(new Vec4(0, 0, 0));        extremes.add(sourceLatLon.getLocation(bc));        Sector sector = Sector.boundingSector(extremes);        GeoQuad destLatLon = new GeoQuad(sector.asList());        double width = destImage.getWidth();        double height = destImage.getHeight();        for (int row = 0; row < destImage.getHeight(); row++)        {            double t = (double) row / height;            for (int col = 0; col < destImage.getWidth(); col++)            {                double s = (double) col / width;                LatLon latLon = destLatLon.interpolate(1 - t, s);                double[] baryCoords = sourceLatLon.getBarycentricCoords(latLon);                Vec4 pixelPostion = sourcePixels.getPoint(baryCoords);                if (pixelPostion.x < 0 || pixelPostion.x >= sourceImage.getWidth()                    || pixelPostion.y < 0 || pixelPostion.y >= sourceImage.getHeight())                    continue;                int pixel = sourceImage.getRGB((int) pixelPostion.x, (int) pixelPostion.y);                destImage.setRGB(col, row, pixel);            }        }        return sector;    }    public static Sector positionImage4(BufferedImage sourceImage, Point[] imagePoints, LatLon[] geoPoints,        BufferedImage destImage)    {        // TODO: check args        BarycentricQuadrilateral sourceLatLon = new BarycentricQuadrilateral(geoPoints[0], geoPoints[1], geoPoints[2],            geoPoints[3]);        BarycentricQuadrilateral sourcePixels = new BarycentricQuadrilateral(imagePoints[0], imagePoints[1],            imagePoints[2], imagePoints[3]);        ArrayList<LatLon> extremes = new ArrayList<LatLon>(4);        // Lower left corner.        double[] bc = sourcePixels.getBarycentricCoords(new Vec4(0, sourceImage.getHeight(), 0));        extremes.add(sourceLatLon.getLocation(bc));        // Lower right corner.        bc = sourcePixels.getBarycentricCoords(new Vec4(sourceImage.getWidth(), sourceImage.getHeight(), 0));        extremes.add(sourceLatLon.getLocation(bc));        // Upper right corner.        bc = sourcePixels.getBarycentricCoords(new Vec4(sourceImage.getWidth(), 0, 0));        extremes.add(sourceLatLon.getLocation(bc));        // Upper left corner.        bc = sourcePixels.getBarycentricCoords(new Vec4(0, 0, 0));        extremes.add(sourceLatLon.getLocation(bc));        Sector sector = Sector.boundingSector(extremes);        GeoQuad destLatLon = new GeoQuad(sector.asList());        double width = destImage.getWidth();        double height = destImage.getHeight();        for (int row = 0; row < destImage.getHeight(); row++)        {            double t = (double) row / height;            for (int col = 0; col < destImage.getWidth(); col++)            {                double s = (double) col / width;                LatLon latLon = destLatLon.interpolate(1 - t, s);                double[] baryCoords = sourceLatLon.getBarycentricCoords(latLon);                Vec4 pixelPostion = sourcePixels.getPoint(baryCoords);                if (pixelPostion.x < 0 || pixelPostion.x >= sourceImage.getWidth()                    || pixelPostion.y < 0 || pixelPostion.y >= sourceImage.getHeight())                    continue;                int pixel = sourceImage.getRGB((int) pixelPostion.x, (int) pixelPostion.y);                destImage.setRGB(col, row, pixel);            }        }        return sector;    }    /**     * Builds a sequence of mipmaps for the specified image. The number of mipmap levels created will be equal to     * <code>maxLevel + 1</code>, including level 0. The level 0 image will be a reference to the original image, not a     * copy. Each mipmap level will be created with the specified BufferedImage type <code>mipmapImageType</code>. Each     * level will have dimensions equal to 1/2 the previous level's dimensions, rownding down, to a minimum width or     * height of 1.     *     * @param image           the BufferedImage to build mipmaps for.     * @param mipmapImageType the BufferedImage type to use when creating each mipmap image.     * @param maxLevel        the maximum mip level to create. Specifying zero will return an array containing the     *                        original image.     *     * @return array of mipmap levels, starting at level 0 and stopping at maxLevel. This array will have length     *         maxLevel + 1.     *     * @throws IllegalArgumentException if <code>image</code> is null, or if <code>maxLevel</code> is less than zero.     * @see #getMaxMipmapLevel     */    public static BufferedImage[] buildMipmaps(BufferedImage image, int mipmapImageType, int maxLevel)    {        if (image == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (maxLevel < 0)        {            String message = Logging.getMessage("generic.ArgumentOutOfRange", "maxLevel < 0");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        BufferedImage[] mipMapLevels = new BufferedImage[1 + maxLevel];        // If the image and mipmap type are equivalent, then just pass the original image along. Otherwise, create a        // copy of the original image with the appropriate image type.        if (image.getType() == mipmapImageType)        {            mipMapLevels[0] = image;        }        else        {            mipMapLevels[0] = new BufferedImage(image.getWidth(), image.getHeight(), mipmapImageType);            drawImageOnCanvas(image, mipMapLevels[0]);        }        for (int level = 1; level <= maxLevel; level++)        {            int width = Math.max(image.getWidth() >> level, 1);            int height = Math.max(image.getWidth() >> level, 1);            mipMapLevels[level] = new BufferedImage(width, height, mipmapImageType);            drawImageOnCanvas(mipMapLevels[level - 1], mipMapLevels[level]);        }        return mipMapLevels;    }    /**     * Builds a sequence of mipmaps for the specified image. This is equivalent to invoking     * <code>buildMipmaps(BufferedImage, int, int)</code>, with <code>mipmapImageType</code> equal to     * <code>image.getType()</code>, and <code>maxLevel</code> equal to <code>getMaxMipmapLevel(image.getWidth(),     * image.getHeight())</code>.     *     * @param image the BufferedImage to build mipmaps for.     *     * @return array of mipmap levels.     *     * @throws IllegalArgumentException if <code>image</code> is null.     */    public static BufferedImage[] buildMipmaps(BufferedImage image)    {        if (image == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        int mipmapImageType = image.getType();        int maxLevel = getMaxMipmapLevel(image.getWidth(), image.getHeight());        // We cannot create a BufferedImage of type "custom", so we fall back to a default image type.        if (mipmapImageType == BufferedImage.TYPE_CUSTOM)        {            mipmapImageType = BufferedImage.TYPE_INT_ARGB;        }        return buildMipmaps(image, mipmapImageType, maxLevel);    }    /**     * Returns the maximum desired mip level for an image with dimensions <code>width</code> and <code>height</code>.     * The maximum desired level is the number of levels required to reduce the original image dimensions to a 1x1     * image.     *     * @param width  the level 0 image width.     * @param height the level 0 image height.     *     * @return maximum mip level for the specified <code>width</code> and <code>height</code>.     *     * @throws IllegalArgumentException if either <code>width</code> or <code>height</code> are less than 1.     */    public static int getMaxMipmapLevel(int width, int height)    {        if (width < 1)        {            String message = Logging.getMessage("generic.ArgumentOutOfRange", "width < 1");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (height < 1)        {            String message = Logging.getMessage("generic.ArgumentOutOfRange", "height < 1");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        int widthLevels = (int) WWMath.logBase2(width);        int heightLevels = (int) WWMath.logBase2(height);        return Math.max(widthLevels, heightLevels);    }    /**     * Returns a copy of the specified image such that the new dimensions are powers of two. The new image dimensions     * will be equal to or greater the original image. The flag <code>scaleToFit</code> determines whether the original     * image should be drawn into the new image with no special scalign, or whether the original image should be scaled     * to fit exactly in the new image. If the original image dimensions are already powers of two, this will simply     * return the original image.     *     * @param image the BufferedImage to convert to a power of two image.     * @param scaleToFit true if <code>image</code> should be scaled to fit the new image dimensions; false otherwise.s     *     * @return copy of <code>image</code> with power of two dimensions.     * @throws IllegalArgumentException if <code>image</code> is null.     */    public static BufferedImage convertToPowerOfTwoImage(BufferedImage image, boolean scaleToFit)    {        if (image == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        // If the original image is already a power of two in both dimensions, then simply return it.        if (WWMath.isPowerOfTwo(image.getWidth()) && WWMath.isPowerOfTwo(image.getHeight()))        {            return image;        }        int potWidth = WWMath.powerOfTwoCeiling(image.getWidth());        int potHeight = WWMath.powerOfTwoCeiling(image.getHeight());        BufferedImage potImage = new BufferedImage(potWidth, potHeight, image.getColorModel().hasAlpha() ?            BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);        Graphics2D g2d = potImage.createGraphics();        try        {            if (scaleToFit)            {                g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);                g2d.drawImage(image, 0, 0, potImage.getWidth(), potImage.getHeight(), null);            }            else            {                g2d.drawImage(image, 0, 0, null);            }        }        finally        {            g2d.dispose();        }        return potImage;    }    /**     * Returns the size in bytes of the specified image. This takes into account only the image's backing DataBuffers,     * and not the numerous supporting classes a BufferedImage references.     *     * @param image the BufferedImage to compute the size of.     *     * @return size of the BufferedImage in bytes.     * @throws IllegalArgumentException if <code>image</code> is null.     */    public static long computeSizeInBytes(BufferedImage image)    {        if (image == null)        {            String message = Logging.getMessage("nullValue.ImageIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        long size = 0L;        java.awt.image.Raster raster = image.getRaster();        if (raster != null)        {            java.awt.image.DataBuffer db = raster.getDataBuffer();            if (db != null)            {                size = computeSizeOfDataBuffer(db);            }        }                return size;    }    private static long computeSizeOfDataBuffer(java.awt.image.DataBuffer dataBuffer)    {        return dataBuffer.getSize() * computeSizeOfBufferDataType(dataBuffer.getDataType());    }

⌨️ 快捷键说明

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