JavaFx在Pane中绘制Image

时间:2016-09-13 06:26:03

标签: java javafx

嗨我想在Pane中绘制图像,当边界高度时我想剪切图像。这张图片由瓷砖组成。一个瓷砖尺寸是256.现在我的完整图像是更大的tham Pane。我不知道如何剪切图像。 嗨,我想绘制一个由瓷砖组成的大图像。一块瓷砖的尺寸为256x256。此图片位于Pane中。此时,图像尺寸大于尺寸Pane。我不知道如何只在Pane画画。谢谢你的帮助

public class TestURLImage8 {

    public static ArrayList<BusStop2> list = new ArrayList<>();
    public static ArrayList<PositionTilesAndURLPaths> positionTilesAndURLPathsList = new ArrayList<>();
    public static HashMap<String, Image> imgCache = new HashMap<>();
    public static double lat;
    public static double lon;
    public static double deltaY;
    public static double deltaX;
    public static double positionX;
    public static double positionY;
    public static int[] imageCount = getCountImage();
    public static int [] countImage = countImage();
    public static int []x = new int [countImage[0]];
    public static int []y = new int [countImage[1]];
    private File file = new File("C:/Users/022/workspace22/EkranLCD/res/images/kropka.png");
    private Image bus = new Image(file.toURI().toString());
    static ArrayList<UtlToImageConverter> threadList = new ArrayList<>(); 


    public TestURLImage8(Pane pane) {
    }

    /**
     * Method use to get count of image what we need 
     * @return
     */
    private static int[] getCountImage(){
        int xImageCount = (int) Math.ceil(Main4.width/256);
        int yImageCount = (int) Math.ceil(Main4.height/256);
        return  new int[] {xImageCount, yImageCount};
    }
    /**
     * Method use to get count of tiles
     * @return
     */
    public static int[] countImage(){
        int xImageCount = imageCount[0];
        int yImageCount = imageCount[1];
        if(xImageCount-1 %2 != 0){
            xImageCount = xImageCount + 2;
        }
        if(yImageCount-1 %2 != 0){
            yImageCount = yImageCount + 2;
        }
        return  new int[] {xImageCount, yImageCount};
    }
    /**
     * Method use to get tiles 
     * @param lat
     * @param lon
     * @return
     */
    private static  ArrayList<BusStop2> getTiles(double lat, double lon ){
        int [] numberTile = getTileNumber(lat, lon, Config.mapZoom);
        int a1 = 1;
        int a2 = 1;
        int a3 = 1;
        int a4 = 1;

        x[0] = numberTile[0];
        y[0] = numberTile[1];
          for (int i = 1; i<x.length; i++){
              if(i%2==0){
                  x[i] = numberTile[0]+(a1);
                  a1++;
              }
              else{
                  x[i] = numberTile[0]-(a2);
                  a2++;
              }
          }

          for (int i = 1; i<y.length; i++){
              if(i%2==0){
                  y[i] = numberTile[1]+(a3);
                  a3++;
              }
              else{
                  y[i] = numberTile[1]-(a4);
                  a4++;
              }
          }

          for(int i = 0 ; i<x.length ; i++){
              for (int j = 0 ;j<y.length ; j++ ){
                  list.add(new BusStop2(x[i], y[j], x[0] - x[i], y[0]-y[j]));       
              }
          }
        return list;
    }
    /**
     * 
     * @param list
     * @return
     */
    private static ArrayList<PositionTilesAndURLPaths> getImgPositionAndURLsPath(ArrayList<BusStop2> list){

        for(BusStop2 bus : list){
            positionTilesAndURLPathsList.add(new PositionTilesAndURLPaths(256*bus.getX(), 256*bus.getY(), 
                    Config.mapPath + "/" + bus.getA() + "/" + bus.getB() + ".png"));
        }
        return positionTilesAndURLPathsList;
    }

     public static int [] getTileNumber(final double lat, final double lon, final int zoom) {
           int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
           int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
            if (xtile < 0)
             xtile=0;
            if (xtile >= (1<<zoom))
             xtile=((1<<zoom)-1);
            if (ytile < 0)
             ytile=0;
            if (ytile >= (1<<zoom))
             ytile=((1<<zoom)-1);
            return  new int[] {xtile, ytile};
           }

     static double tile2lon(int x, int z) {
         return x / Math.pow(2.0, z) * 360.0 - 180;
      }

      static double tile2lat(int y, int z) {
        double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);
        return Math.toDegrees(Math.atan(Math.sinh(n)));
      }

    public void start(Pane pane ,double lat, double lon) throws Exception {
        int [] tiles= getTileNumber(lat, lon, Config.mapZoom);

        Canvas canvas = new Canvas(Config.xSize, Config.ySize);
        GraphicsContext gc = canvas.getGraphicsContext2D(); 
        int [] aa =getTileNumber(lat,lon, Config.mapZoom);
        getTiles(lat,lon); 
        getImgPositionAndURLsPath(list);


        ExecutorService executor = Executors.newFixedThreadPool(10);
        ArrayList<UtlToImageConverter2> threadList = new ArrayList<>(); 
        for(PositionTilesAndURLPaths url : positionTilesAndURLPathsList){
            threadList.add(new UtlToImageConverter2(url.getPath()));
        }
        try {
            executor.invokeAll(threadList);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(imgCache.size());
        System.out.println( aa[0] + " " + aa[1] );
        deltaX = tile2lon(tiles[0] + 1 , Config.mapZoom) -  tile2lon(tiles[0], Config.mapZoom);
        deltaY = tile2lat(tiles[1], Config.mapZoom) - tile2lat(tiles[1] + 1 , Config.mapZoom);
        positionX = (lon - tile2lon(tiles[0], Config.mapZoom)) * Config.imgSize/deltaX;
        positionY = (tile2lat(tiles[1], Config.mapZoom) - lat) * Config.imgSize/deltaY;

        gc.drawImage(bus,847.0-100 ,621.0-100);
        gc.strokeText("aalala", 847.0-10 ,621.0-10);

        for(PositionTilesAndURLPaths pos : getImgPositionAndURLsPath(list)){
            gc.drawImage(imgCache.get(pos.getPath()),Config.xSize/2-pos.getX()-Config.imgSize/2 ,(Config.ySize/2)- pos.getY()-Config.imgSize/2, Config.imgSize, Config.imgSize);
            System.out.println(pos.getX() + " " + pos.getY());
        }
        gc.drawImage(bus,Config.xSize/2-Config.imgSize/2-Config.markWidth/2+positionX, Config.ySize/2+positionY-Config.imgSize/2-Config.markHeight/2, Config.markWidth, Config.markHeight);
        pane.getChildren().add(canvas);    
    }
    @SuppressWarnings("unused")
    public static void clear(){
            for(PositionTilesAndURLPaths url : positionTilesAndURLPathsList){
                url = null;
            }
            positionTilesAndURLPathsList.clear();
            threadList.clear();
            for(UtlToImageConverter utl : threadList){
                utl = null;
            }
            for(BusStop2 bus :list){
                bus = null;
            }
            list.clear();
    }
}

1 个答案:

答案 0 :(得分:0)

在JavaFX中有多个选项可以显示图像的一部分:

使用Canvas节点时,请使用the correct drawImage,即不将图像缩放到目标矩形的节点。 e.g。

Rectangle2D rectInSource = ...
Rectangle2D targetRect = ...
gc.drawImage(image,
             rectInSource.getMinX(),
             rectInSource.getMinY(),
             rectInSource.getWidth(),
             rectInSource.getHeight(),
             targetRect.getMinX(),
             targetRect.getMinY(),
             targetRect.getWidth(),
             targetRect.getHeight());

或者,您也可以使用ImageView通过相应地设置viewport property来显示Image的一部分:

ImageView imageView = new ImageView(image);
imageView.setViewport(rectInSource);

// ----------- Only required, if rescaling is desired -----------
imageView.setFitWidth(targetRect.getWidth());
imageView.setFitHeight(targetRect.getHeight());
// --------------------------------------------------------------

imageView.relocate(targetRect.getMinX(), targetRect.getMinY());
pane.getChildren().add(imageView);

rectInSource表示应显示的图像部分,targetRect应绘制的位置。