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 + -
显示快捷键?