    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}