tiler
tiler copied to clipboard
下载后切片镶嵌是否有相关工具呀
下载后切片镶嵌是否有相关工具呀,或者您是怎么后续处理镶嵌的
木有,后续可以考虑搞个小工具
是拼图吗?我用go写了一个,但是和你的机理稍微有点区别,我发给你看看能否改改支持你的拼接?
我用Trae AI编辑器很快就写好了几个拼图的程序。
package main
import (
"flag"
"fmt"
"image"
"image/color"
"image/draw"
_ "image/gif"
_ "image/jpeg" // 坑:这里一定要引入这个才能解析jpeg格式的图片!!!即使不需要,也要这样引入_ "image/jpeg"
"image/png"
"os"
"path/filepath"
"strconv"
"strings"
)
// Tile 表示单个瓦片
type Tile struct {
Z, X, Y int
Img image.Image
}
func main() {
// 命令行参数
currentDir, err := os.Getwd()
if err != nil {
return
}
baseDir := flag.String("dir", currentDir, "瓦片存储根目录")
outputFile := flag.String("combineinpath", "combininpath.png", "输出文件名")
zoom := flag.Int("zoom", -1, "指定缩放层级,默认为-1(自动检测所有层级)")
flag.Parse()
// 验证输入
if _, err := os.Stat(*baseDir); os.IsNotExist(err) {
fmt.Printf("错误: 目录 %s 不存在\n", *baseDir)
os.Exit(1)
}
// 读取瓦片
tiles, err := readTiles(*baseDir, *zoom)
// fmt.Print(tiles)
if err != nil {
fmt.Printf("读取瓦片失败: %v\n", err)
os.Exit(1)
}
if len(tiles) == 0 {
fmt.Println("没有找到瓦片")
os.Exit(1)
}
// 确定缩放层级
currentZoom := tiles[0].Z
for _, tile := range tiles {
if tile.Z != currentZoom {
fmt.Println("错误: 发现多个缩放层级的瓦片,请使用-zoom参数指定一个层级")
os.Exit(1)
}
}
// 拼接瓦片resultImg
resultImg, err := stitchTiles(tiles)
if err != nil {
fmt.Printf("拼接瓦片失败: %v\n", err)
os.Exit(1)
}
// 保存结果
if err := saveImage(resultImg, *outputFile); err != nil {
fmt.Printf("保存图像失败: %v\n", err)
os.Exit(1)
}
fmt.Printf("成功拼接瓦片并保存到 %s\n", *outputFile)
}
// readTiles 读取指定目录下的所有瓦片
func readTiles(baseDir string, targetZoom int) (tiles []Tile, err error) {
// var tiles []Tile
// 遍历目录
err = filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// fmt.Printf(path)
// 跳过目录
if info.IsDir() {
return nil
}
// 检查文件是否为PNG
if !strings.HasSuffix(strings.ToLower(path), ".png") {
// fmt.Printf(path)
return nil
}
// 解析路径获取z, x, y
relPath, err := filepath.Rel(baseDir, path)
if err != nil {
return err
}
parts := strings.Split(relPath, string(filepath.Separator))
if len(parts) < 3 {
return nil // 路径不符合z/x/y.png格式
}
// fmt.Printf(parts[1])
// 解析z, x, y
z, err := strconv.Atoi(parts[0])
if err != nil {
return nil
}
// 如果指定了缩放层级,则只处理该层级
if targetZoom != -1 && z != targetZoom {
return nil
}
x, err := strconv.Atoi(parts[1])
if err != nil {
return nil
}
// 去除文件扩展名
yStr := strings.TrimSuffix(parts[2], ".png")
y, err := strconv.Atoi(yStr)
if err != nil {
fmt.Print(tiles)
return nil
}
// 读取图像
img, err := loadImage(path)
if err != nil {
fmt.Printf("警告: 无法读取图像 %s: %v\n", path, err)
return nil
}
// 添加到瓦片列表
tiles = append(tiles, Tile{
Z: z,
X: x,
Y: y,
Img: img,
})
// fmt.Print(tiles)
return nil
})
// fmt.Print(tiles)
return tiles, err
}
// loadImage 加载图像文件
func loadImage(path string) (image.Image, error) {
file, err := os.Open(path)
if err != nil {
// fmt.Print(err)
return nil, err
}
defer file.Close()
img, _, err := image.Decode(file)
// fmt.Print(err)
return img, err
}
// stitchTiles 拼接瓦片
func stitchTiles(tiles []Tile) (image.Image, error) {
if len(tiles) == 0 {
return nil, fmt.Errorf("瓦片列表为空")
}
// 确定瓦片尺寸(假设所有瓦片大小相同)
tileWidth := tiles[0].Img.Bounds().Dx()
tileHeight := tiles[0].Img.Bounds().Dy()
// 找出X和Y的最小和最大值
minX, maxX := tiles[0].X, tiles[0].X
minY, maxY := tiles[0].Y, tiles[0].Y
for _, tile := range tiles {
if tile.X < minX {
minX = tile.X
}
if tile.X > maxX {
maxX = tile.X
}
if tile.Y < minY {
minY = tile.Y
}
if tile.Y > maxY {
maxY = tile.Y
}
}
// 计算输出图像的尺寸
width := (maxX - minX + 1) * tileWidth
height := (maxY - minY + 1) * tileHeight
// 创建输出图像
resultImg := image.NewRGBA(image.Rect(0, 0, width, height))
bgColor := color.White
draw.Draw(resultImg, resultImg.Bounds(), &image.Uniform{bgColor}, image.Point{}, draw.Src)
// 绘制每个瓦片到正确的位置
for _, tile := range tiles {
xOffset := (tile.X - minX) * tileWidth
yOffset := (tile.Y - minY) * tileHeight
draw.Draw(resultImg,
image.Rect(xOffset, yOffset, xOffset+tileWidth, yOffset+tileHeight),
tile.Img,
image.Point{},
draw.Over)
}
return resultImg, nil
}
// saveImage 保存图像到文件
func saveImage(img image.Image, filePath string) error {
file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()
return png.Encode(file, img)
}