简体   繁体   English

JavaFx在窗格中绘制图像

[英]JavaFx draw Image inside in Pane

Hi I want to drawing image inside in Pane , when a bounds are heigh I want to cut image. 嗨,我想在Pane内绘制图像,当边界很高时,我想剪切图像。 This image consists of tile. 该图像由图块组成。 One tile size is 256. Now my full image is bigger tham Pane. 一个图块大小是256。现在我的完整图像是tham Pane。 I don't know how I can cut image. 我不知道该如何剪切图像。 Hi I want to draw one large image, which consists of tiles. 嗨,我想画一张大图,由瓷砖组成。 One tile has dimensions of 256x256. 一个图块的尺寸为256x256。 This image is in Pane. 此图像在窗格中。 At this time, image dimensions are larger than the dimension Pane. 此时,图像尺寸大于“窗格”尺寸。 I do not know how to do to draw only in Pane. 我不知道如何只在窗格中绘制。 Thanks for help 感谢帮助

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();
    }
}

There are multiple options to display a part of a image in JavaFX: 有多个选项可显示JavaFX中图像的一部分:

When using a Canvas node, use the correct drawImage , ie the one that does not scale the image to the target rectangle. 使用Canvas节点时,请使用正确的drawImage ,即不会将图像缩放到目标矩形的drawImage eg 例如

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

Alternatively you could also use a ImageView for displaying part of a Image by setting the viewport property accordingly: 或者你也可以使用一个ImageView用于显示的部分Image通过设置viewport属性相应:

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 denotes the part of the image that should be displayed, targetRect the position where it should be drawn. rectInSource表示应显示的图像部分, targetRect绘制位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM