美文网首页SpringBoot
大图片分割成EPSG:3857栅格瓦片

大图片分割成EPSG:3857栅格瓦片

作者: WebGiser | 来源:发表于2023-04-11 21:06 被阅读0次
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.test</groupId>
    <artifactId>CutImageTile</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>CutImageTile</name>

    <properties>
        <maven-jar-plugin.version>3.0.0</maven-jar-plugin.version>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <build>
        <finalName>CutImageTile</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>org.test.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
package org.test;


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;

/**
 * 图片裁剪工具
 */
public class ImageHandler {

    /**
     * 裁剪图片
     *
     * @param originImgPath 原始图片的路径
     * @param outTilePath   输出的瓦片路径(最好是空文件夹)
     * @param tileFormat    输出的瓦片格式(jpg、png)
     * @param bgColor       空白处的背景颜色 [reb,green,bule,alpha]
     * @throws Exception
     */
    public void cutImageTile(String originImgPath, String outTilePath, String tileFormat, int[] bgColor) throws Exception {

        // 读取原始大图的信息
        File file = new File(originImgPath);
        FileInputStream fis = new FileInputStream(file);
        BufferedImage image = ImageIO.read(fis);
        int width = image.getWidth();
        int height = image.getHeight();
        int imageType = image.getType();
        double scale = width / height;
        System.out.printf("原始图片宽度:%d,高度:%d,;宽高比例:%f,类型:%d \n", width, height, scale, imageType);


        // 切片大小 256*256
        int tileSize = 256;

        // 根据原始大图的宽高像素,自动计算切片的最大层级
        int maxPixel = Math.max(width, height);
        double num = maxPixel / tileSize;
        int zoom = 0;
        for (zoom = 0; zoom < 18; zoom++) {
            int num2 = (int) Math.pow(2, zoom);
            if (num < num2) {
                break;
            }
        }
        System.out.printf("自动计算的最大切片层级:%d \n", zoom);

        // 对每个层级进行切图(3857)
        // 思路:先将原始大图等比例缩放到某个zoom层级下的缩略图,然后对缩略图进行3857的切分
        for (int level = 0; level <= zoom; level++) {
            // 创建层级文件夹
            File tileFile = new File(outTilePath + "\\" + level);
            if (!tileFile.exists() || tileFile.isFile()) {
                tileFile.mkdir();
            }

            // 计算3857坐标系下各层级的行列数
            int rows = (int) Math.pow(2, level);
            int cols = (int) Math.pow(2, level);
            int tileSum = rows * cols;
            System.out.printf("层级:%d,行数:%d,列数:%d,切片数量:%d \n", level, rows, cols, tileSum);

            // 获取某个层级下的等比例缩放图(为了校验)
            int zoomWidth = cols * tileSize;
            int zoomHeight = (int) (cols * tileSize / scale);
            Image scaleImage = image.getScaledInstance(zoomWidth, zoomHeight, Image.SCALE_SMOOTH);
            BufferedImage temp = new BufferedImage(zoomWidth, zoomHeight, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D graphics = temp.createGraphics();
            graphics.drawImage(scaleImage, 0, 0, zoomWidth, zoomHeight, 0, 0, zoomWidth, zoomHeight, null);
            graphics.dispose();
            ImageIO.write(temp, tileFormat, new File(outTilePath + "\\" + level + "." + tileFormat));

            for (int row = 0; row < rows; row++) {
                for (int col = 0; col < cols; col++) {
                    // 创建列文件夹
                    File colFile = new File(tileFile.getAbsolutePath() + "\\" + col);
                    if (!colFile.exists() || colFile.isFile()) {
                        colFile.mkdir();
                    }

                    // 创建切片,并写入图像内容
                    BufferedImage bufferedImage = new BufferedImage(tileSize, tileSize, BufferedImage.TYPE_4BYTE_ABGR);
                    Graphics2D gr = bufferedImage.createGraphics();
                    int sx1 = col * tileSize;
                    int sx2 = (col + 1) * tileSize;
//                    int sy1 = (int) ((row - rows / 2) * tileSize);
//                    int sy2 = (int) ((row + 1 - rows / 2) * tileSize);
                    int sy1 = row * tileSize;
                    int sy2 = (row + 1) * tileSize;
                    gr.setColor(new Color(bgColor[0], bgColor[1], bgColor[2], bgColor[3]));
                    gr.fillRect(0, 0, tileSize, tileSize);
                    gr.drawImage(scaleImage, 0, 0, tileSize, tileSize, sx1, sy1, sx2, sy2, null);
                    gr.dispose();
                    // 保存切片
                    File tile = new File(colFile.getAbsolutePath() + "\\" + row + "." + tileFormat);
                    ImageIO.write(bufferedImage, tileFormat, tile);
                }
            }
        }
        System.out.println("完成分割!");
    }
}
package org.test;

import org.test.ImageHandler;

public class App {
    public static void main(String[] args) throws Exception {

//        直接设置参数
        String originalImg = "D:\\study\\test\\03232.png";
        String outTilePath = "D:\\study\\test\\temp";
        String tileFormat = "png";
        int[] bgColor = new int[]{205, 221, 241, 50};
        ImageHandler imageHandler = new ImageHandler();
        imageHandler.cutImageTile(originalImg, outTilePath, tileFormat, bgColor);

//        从jar包命令行获取参数
//        String originImg = System.getProperty("originImg");
//        String outTilePath = System.getProperty("outTilePath");
//        String tileFormat = System.getProperty("tileFormat");
//        int red = Integer.valueOf(System.getProperty("red"));
//        int green = Integer.valueOf(System.getProperty("green"));
//        int blue = Integer.valueOf(System.getProperty("blue"));
//        int alpha = Integer.valueOf(System.getProperty("alpha"));
//        int[] bgColor = new int[]{red, green, blue, alpha};
//        ImageHandler imageHandler = new ImageHandler();
//        imageHandler.cutImageTile(originImg, outTilePath, tileFormat, bgColor);

    }
}

相关文章

网友评论

    本文标题:大图片分割成EPSG:3857栅格瓦片

    本文链接:https://www.haomeiwen.com/subject/ndkcddtx.html