2021-05-28

瓦片图是什么呢

	指将一定范围内的地图按照一定的尺寸和格式,按缩放级别或者比例尺,
    切成若干行和列的正方形栅格图片,对切片后的正方形栅格图片被形象的称为瓦片

一幅精确到街道级别的世界地图图片宽度为数以百万计的像素,
由于这些数据太大了,从而导致无法一次下载并且在内存里也无法一次都hold住。
实际上,Web地图由许多小的正方形的图片组成,这些小图片称作瓦片。
瓦片的大小一般为256*256像素,这些瓦片一个挨一个并列放置以组成一张很大的看似无缝的地图。

高德命名方式

链接: link.
上面链接能够充分的看出命名规则

切图

直接上代码(由于是瓦片图,所以原图较大,用java的BufferedImage我还没有找到怎么读取大图,所以用的是Iterator)

/**
     * 图片裁切
     * @param sourcePath 源图片路径
     */
    public static String cut(String sourcePath) {
        String descPath = "";

        FileInputStream is = null;
        ImageInputStream iis = null;
        int x1 = 0;
        int y1 = 0;
        try {
            is = new FileInputStream(sourcePath);
            String fileSuffix = sourcePath.substring(sourcePath.lastIndexOf(".") + 1);
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(fileSuffix);
            ImageReader reader = it.next();
            iis = ImageIO.createImageInputStream(is);
            reader.setInput(iis, true);
            ImageReadParam param = reader.getDefaultReadParam();
            //原始图宽度
            int w = reader.getWidth(0);
            //原始图高度
            int h = reader.getHeight(0);
            //一行有多少个256
            int l;
            int b;
            //切片的边长
            int ll;
            //层级 1234567
            int n = 1;
            if (w>h){
                ll=h;
            }else{
                ll=w;
            }
            while (ll%256!=0){
                ll--;
            }
            l=ll/256;
            while (!((b=l/2) ==1)){
                l=b;
                n++;
            }
            //创建文件夹
            create(n+2);
            l = (int) Math.pow(2,n);
            //切图初始x坐标
            int left = w-l*256/2;
            //切图初始y坐标
            int top = h-l*256/2;
            for (int i=0;i<l;i++){
                for (int j=0;j<l;j++){
                    x1 = left+i*256;
                    y1 = top+j*256;
                    descPath = "图片上层文件夹的目录"+(n+2)+"/"+(l+i)+"_"+(l+j)+".jpg";
                    Rectangle rect = new Rectangle(x1, y1, 256, 256);
                    param.setSourceRegion(rect);
                    BufferedImage bi = reader.read(0, param);
                    bi.getHeight();
                    bi.getWidth();
                    ImageIO.write(bi, fileSuffix, new File(descPath));
                }
            }
            for(int i = n;i>1;i--){
                pin((int) (Math.pow(2,(i-2))*3),(i+1),l);
            }
            return "目录";
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                is = null;
            }
            if (iis != null) {
                try {
                    iis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                iis = null;
            }
        }
        return null;
    }

代码只是切了原图那层,需要缩放

/**
     * 缩放
     * @param file
     * @param z
     * @param path1
     * @param path
     * @throws Exception
     */
    public static void zoomImage(File file,double z,String path1, String path)throws Exception{
        BufferedImage bufImg = ImageIO.read(file);
        BufferedImage bi = ImageIO.read(new File(path1));
        int w = (int) (bi.getWidth()*z);
        int h = (int) (bi.getHeight()*z);
        //新生成结果图片
        BufferedImage zoomImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //缩放 getScaledInstance(width,height,hints)
        zoomImg.getGraphics().drawImage(bufImg.getScaledInstance(w, h, Image.SCALE_SMOOTH), 0, 0, null);
        ImageIO.write(zoomImg,"jpg",new File(path));

    }
    /**
     *
     *
     * @param
     * @param
     * @paramisHorizontal 为true时表示水平方向合并,为false时表示垂直方向合并
     * @return返回合并后的BufferedImage对象
     * @throwsIOException
     */
    /**
     *
     * @param a 缩放之后的命名起始
     * @param c 缩放之后的文件夹名称(3,4,5,6.....)
     * @param l 被缩放的层级的边长是多少个256
     * @throws Exception
     */
    public static void pin(int a,int c,int l) throws Exception {
        int b;
        for (int i = (a*2);i<(a*2+l);i++){
            b=a;
            for (int j = (a*2);j<(a*2+l);j++){
                pinjie(i,j,a,b,c);
                j++;
                b++;
            }
            i++;
            a++;
        }

    }
    public static String pinjie(int i,int j,int a,int b,int c) throws Exception {
        BufferedImage img1;
        BufferedImage img2;
        boolean isHorizontal;
        BufferedImage img3;

        img1 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+i+"_"+j+".jpg"));
        img2 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+i+"_"+(j+1)+".jpg"));
        isHorizontal = false;
        img3 = mergeImage(img1, img2, isHorizontal);
        File outputfile1 = new File("/app/cut/000/ll.jpg");
        ImageIO.write(img3, "jpg", outputfile1);

        img1 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+(i+1)+"_"+j+".jpg"));
        img2 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+(i+1)+"_"+(j+1)+".jpg"));
        isHorizontal = false;
        img3 = mergeImage(img1, img2, isHorizontal);
        File outputfile2 = new File("/app/cut/000/rr.jpg");
        ImageIO.write(img3, "jpg", outputfile2);

        img1 = ImageIO.read(new File("/app/cut/000/ll.jpg"));
        img2 = ImageIO.read(new File("/app/cut/000/rr.jpg"));
        isHorizontal = true;
        img3 = mergeImage(img1, img2, isHorizontal);
        File outputfile = new File("/app/cut/000/he.jpg");
        ImageIO.write(img3, "jpg", outputfile);

        String path = "/app/cut/000/he.jpg";
        File file = new File(path);

        String path1 = "/app/cut/tiles/"+c+"/"+a+"_"+b+".jpg";
		//缩放为原来的0.5倍
        zoomImage(file,0.5,path,path1);
        return path1;
    }

    public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2, boolean isHorizontal) throws IOException {

        int w1 = img1.getWidth();

        int h1 = img1.getHeight();

        int w2 = img2.getWidth();

        int h2 = img2.getHeight();

        //从图片中读取RGB

        int[] ImageArrayOne = new int[w1 * h1];

        ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);//逐行扫描图像中各个像素的RGB到数组中

        int[] ImageArrayTwo = new int[w2 * h2];

        ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);

//生成新图片

        BufferedImage DestImage = null;

        if (isHorizontal) {//水平方向合并

            DestImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);

            DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);//设置上半部分或左半部分的RGB

            DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);

        } else {//垂直方向合并

            DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);

            DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);//设置上半部分或左半部分的RGB

            DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2);//设置下半部分的RGB

        }

        return DestImage;

    }

    static int flag = 1;//用来判断文件是否删除成功

    public static void remove() {
        //删除一个文件夹下的所有文件(包括子目录内的文件)
        File file = new File("删除的文件夹");//输入要删除文件目录的绝对路径
        deleteFile(file);
        if (flag == 1) {
            System.out.println("文件删除成功!");
        }
    }

    public static void deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            flag = 0;
            System.out.println("文件删除失败,请检查文件路径是否正确");
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //打印文件名
            String name = file.getName();
            System.out.println(name);
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                deleteFile(f);
            } else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }


    public static void create(int num) {

        // 在D盘创建一个文件夹
        File file = new File("/app/cut/tiles/");
        file.mkdirs();
        for (int i = 3;i<(num+1);i++){
            File file1 = new File("/app/cut/tiles/"+i);
            file1.mkdirs();
        }

    }

做个记录,第一次搞这个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值