001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.plugins.streetside.cubemap; 003 004import java.awt.geom.AffineTransform; 005import java.awt.image.AffineTransformOp; 006import java.awt.image.BufferedImage; 007 008import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 009import org.openstreetmap.josm.tools.Logging; 010 011import javafx.application.Platform; 012import javafx.scene.image.PixelWriter; 013import javafx.scene.image.WritableImage; 014 015@SuppressWarnings({ "restriction"}) 016public class GraphicsUtils { 017 018 public static javafx.scene.image.Image convertBufferedImage2JavaFXImage(BufferedImage bf) { 019 WritableImage wr = null; 020 if (bf != null) { 021 wr = new WritableImage(bf.getWidth(), bf.getHeight()); 022 PixelWriter pw = wr.getPixelWriter(); 023 for (int x = 0; x < bf.getWidth(); x++) { 024 for (int y = 0; y < bf.getHeight(); y++) { 025 pw.setArgb(x, y, bf.getRGB(x, y)); 026 } 027 } 028 } 029 return wr; 030 } 031 032 public static class PlatformHelper { 033 034 public static void run(Runnable treatment) { 035 if(treatment == null) throw new IllegalArgumentException("The treatment to perform can not be null"); 036 037 if(Platform.isFxApplicationThread()) treatment.run(); 038 else Platform.runLater(treatment); 039 } 040 } 041 042 public static BufferedImage buildMultiTiledCubemapFaceImage(BufferedImage[] tiles) { 043 044 BufferedImage res = null; 045 046 int pixelBuffer = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?2:1; 047 048 tiles = cropMultiTiledImages(tiles, pixelBuffer); 049 050 int rows = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2; //we assume the no. of rows and cols are known and each chunk has equal width and height 051 int cols = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?4:2; 052 053 int chunkWidth, chunkHeight; 054 055 chunkWidth = tiles[0].getWidth(); 056 chunkHeight = tiles[0].getHeight(); 057 058 //Initializing the final image 059 BufferedImage img = new BufferedImage(chunkWidth*cols, chunkHeight*rows, BufferedImage.TYPE_INT_ARGB); 060 061 int num = 0; 062 for (int i = 0; i < rows; i++) { 063 for (int j = 0; j < cols; j++) { 064 // TODO: this makes the image a mirror image. why!?! 065 img.createGraphics().drawImage(tiles[num], chunkWidth * j, chunkHeight * i, null); 066 067 // TODO: remove file test! 068 /*try { 069 ImageIO.write(img, "jpeg", new File("/Users/renerr18/Desktop/TileImagesTest/tile16b" + Long.valueOf(System.currentTimeMillis()).toString() + "createGraphicsAfter.jpeg")); 070 //ImageIO.write(res[i], "jpeg", outputfileAfter); 071 } catch (IOException e) { 072 // TODO Auto-generated catch block 073 e.printStackTrace(); 074 }*/ 075 076 int width = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510; 077 int height = StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510; 078 079 // BufferedImage for mirror image 080 res = new BufferedImage(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510, StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()?1014:510, 081 BufferedImage.TYPE_INT_ARGB); 082 083 // Create mirror image pixel by pixel 084 for (int y = 0; y < height; y++) 085 { 086 for (int lx = 0, rx = width - 1; lx < width; lx++, rx--) 087 { 088 // lx starts from the left side of the image 089 // rx starts from the right side of the image 090 // lx is used since we are getting pixel from left side 091 // rx is used to set from right side 092 // get source pixel value 093 int p = img.getRGB(lx, y); 094 095 // set mirror image pixel value 096 res.setRGB(rx, y, p); 097 } 098 } 099 num++; 100 } 101 } 102 103 Logging.debug("Image concatenated....."); 104 105 return res; 106 } 107 108 public static BufferedImage rotateImage(BufferedImage bufImg) { 109 AffineTransform tx = AffineTransform.getScaleInstance(-1, -1); 110 tx.translate(-bufImg.getWidth(null), -bufImg.getHeight(null)); 111 AffineTransformOp op = new AffineTransformOp(tx, 112 AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 113 bufImg = op.filter(bufImg, null); 114 return bufImg; 115 } 116 117 private static BufferedImage[] cropMultiTiledImages(BufferedImage[] tiles, int pixelBuffer) { 118 119 BufferedImage[] res = new BufferedImage[tiles.length]; 120 121 for(int i=0; i<tiles.length;i++) { 122 if(StreetsideProperties.SHOW_HIGH_RES_STREETSIDE_IMAGERY.get()) { 123 res[i] = tiles[i].getSubimage(pixelBuffer, pixelBuffer, 256-pixelBuffer, 256-pixelBuffer); 124 } else { 125 res[i] = tiles[i].getSubimage(pixelBuffer, pixelBuffer, 256-pixelBuffer, 256-pixelBuffer); 126 } 127 } 128 return res; 129 } 130}