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