背景
在很多场景中,需要用的影像瓦片,常规的思路是将tif进行切图,做成分层的瓦片:
但是,如果层级太高,产生的文件将十分庞大,据测试,某地级市18层级切片,内存占用高达200多G,在部署和传输的过程中,都很不利。
通用处理
因此,采取的思路是如何能够压缩每一张图层,在尽可能保留原有分辨率和色彩的同时,减少影像图片内存的大小。
最初采用开源压缩工具:pngquant
windows下有GUI版本,但是GUI版本只能针对单文件,我们需要运行它的核心文件:pngquanti.exe。
其单文件处理命令为:pngquant --quality=65-80 input.png
但是很明显,这种方式并不适用,因为影像瓦片涉及每一个层级文件夹,层级文件夹里还有索引文件夹,因此,需要一个命令来遍历文件夹,找到其中的影像文件,压缩后并替换:
for /r "C:\path\to\your\3dtiles" %i in (*.png) do "C:\path\to\pngquant.exe" --ext .png --force --quality=65-80 "%i"
将文件夹和处理程序的地址替换即可。
改进处理
上述方法似乎已经解决了之前的问题,但是如果数据量太大,依然面临着一个不能忽视的问题,那就是处理时间太长,那能否调用多线程来实现多步压缩处理呢?事实是可行的,为了能够实现多线程,且用户自定义线程数,可以通过python构建一个简单的GUI程序,加上一个进度条,查看文件处理进展。
界面设计如下:
def __init__(self, master):
self.master = master
master.title("PNG优化工具 (多线程版)")
self.pngquant_path = tk.StringVar()
self.folder_path = tk.StringVar()
self.num_threads = tk.IntVar(value=4) # 默认线程数
tk.Label(master, text="PNGQuant路径:").grid(row=0, column=0, sticky="e")
tk.Entry(master, textvariable=self.pngquant_path, width=50).grid(row=0, column=1)
tk.Button(master, text="浏览", command=self.browse_pngquant).grid(row=0, column=2)
tk.Label(master, text="文件夹路径:").grid(row=1, column=0, sticky="e")
tk.Entry(master, textvariable=self.folder_path, width=50).grid(row=1, column=1)
tk.Button(master, text="浏览", command=self.browse_folder).grid(row=1, column=2)
tk.Label(master, text="线程数:").grid(row=2, column=0, sticky="e")
tk.Entry(master, textvariable=self.num_threads, width=5).grid(row=2, column=1, sticky="w")
self.start_button = tk.Button(master, text="开始处理", command=self.start_processing)
self.start_button.grid(row=3, column=1)
self.progress = ttk.Progressbar(master, length=300, mode='determinate')
self.progress.grid(row=4, column=0, columnspan=3, pady=10)
self.log = tk.Text(master, height=10, width=60)
self.log.grid(row=5, column=0, columnspan=3)
self.file_queue = queue.Queue()
self.total_files = 0
self.processed_files = 0
程序运行效果:
压缩效率对比
17层级文件夹:
- 原始大小:22GB
- 现在大小:5.57GB