Important

rgb值 37 37 37是海平面,高于它的的陆地,低于它的是海洋

准备

  1. QGIS两个版本随便下
  2. GIMP点击黄色图标下载
  3. NASA Heightmap下载所有GeoTIFF文件
  4. Natural Earth点击 Downloads 下载矢量文件 点击 Physical 找到 rivers&lakes 下载 退回去找到 cultrual 下载 下载 countries

开始

  1. 打开 QGIS

  2. 可以看到左边有计算机的盘符,找到下载的 NASA Hheightmap 文件,拖到下面的空白处

  3. 当然,你也可以在文件夹里就拖拽到QGIS

  4. 点击 栅格—>杂项—>合并

  5. 点击输入图层右边的选项

  6. 点击全选

  7. 点击箭头返回

  8. 输出数据类型选择 int8

  9. 合并输出选择保存到文件,选择一个地方保存,文件名字随意,然后点击运行

  10. 合并完成,完成之后,之前的几个栅格文件就没用了,可以移除掉,当然不移除也可以,把前面的勾勾掉,就不显示在右侧了

  11. 把之前下载的 countries,lakes,rivers 压缩包解压,选择其中的 shp 文件,拖到QGIS里

  12. 选择右下角的 epsg:4326 ,过滤那里输入 3035 ,在下面的坐标系中选择 3035 ,点击 Apply ,可以发现,投影变了,最后点击 OK

  13. 点击 栅格—>投影—>重投影 ,选择合并后的栅格文件,源CRS选择 4326 ,目标CRS选择 3035 ,选个地方保存。运行。运行之时会有一系列报错,这个不用管。

  14. 点击 矢量—>数据管理工具—>重投影图层 ,有三个图层,为每一个图层进行转换,目标CRS为 3035 ,保存为shp文件

  15. 转换完成

  16. 我们分别为各个图层创建 PNG 文件,去掉图层左边的勾,先让一个图层显示。点击下面的比例尺设置为 1:10000000 ,点击左上角 工程—>导入/导出—>导出地图为图像 ,由于显示的是 rivers 图层,那么这里的图层也选择 rivers 图层,分辨率选择 200 ,然后 save,宽度和高度不用管。选择一个地方保存。

  17. 按照同样的步骤给其它图层导出为 PNG

  18. 编写python脚本,删除PNG里的rgb值为 255 255 255的像素,把其它像素rgb值设为 0 0 0,作用于lakes和rivers图片。Python地址,pip安装命令: pip install numpy pillow

from tkinter import Tk, filedialog
from PIL import Image
import numpy as np

# 增加 PIL 的图像大小限制
Image.MAX_IMAGE_PIXELS = None

def process_png(input_path):
    # 打开PNG文件
    img = Image.open(input_path)
    img = img.convert("RGBA")
    data = np.array(img)

    # 创建一个布尔掩码,找到需要处理的像素
    mask_white = (data[:, :, :3] == [255, 255, 255]).all(axis=2)
    mask_non_white = ~mask_white

    # 将白色像素设为透明
    data[mask_white] = [255, 255, 255, 0]

    # 将非白色像素改为 (0, 0, 0)
    data[mask_non_white] = [0, 0, 0, 255]

    # 创建处理后的图像
    processed_img = Image.fromarray(data, 'RGBA')
    output_path = input_path.replace(".png", "_processed.png")
    processed_img.save(output_path, "PNG")

# 创建一个Tkinter根窗口并隐藏它
root = Tk()
root.withdraw()

# 打开文件对话框,选择PNG文件
file_path = filedialog.askopenfilename(filetypes=[("PNG files", "*.png")])

# 处理选中的文件
if file_path:
    process_png(file_path)
    print(f"处理完成:{file_path.replace('.png', '_processed.png')}")

print("所有文件处理完成。")

  1. 写一个python脚本,删除rgb为255 255 255的像素,将其它像素rgb设为41 41 41,作用于countries.png
from tkinter import Tk, filedialog
from PIL import Image
import numpy as np

# 增加 PIL 的图像大小限制
Image.MAX_IMAGE_PIXELS = None

def process_png(input_path):
    # 打开PNG文件
    img = Image.open(input_path)
    img = img.convert("RGBA")
    data = np.array(img)

    # 创建一个布尔掩码,找到需要处理的像素
    mask_white = (data[:, :, :3] == [255, 255, 255]).all(axis=2)
    mask_non_white = ~mask_white

    # 将白色像素设为透明
    data[mask_white] = [255, 255, 255, 0]

    # 将非白色像素改为 (41, 41, 41)
    data[mask_non_white] = [41, 41, 41, 255]

    # 创建处理后的图像
    processed_img = Image.fromarray(data, 'RGBA')
    output_path = input_path.replace(".png", "_processed.png")
    processed_img.save(output_path, "PNG")

# 创建一个Tkinter根窗口并隐藏它
root = Tk()
root.withdraw()

# 打开文件对话框,选择PNG文件
file_path = filedialog.askopenfilename(filetypes=[("PNG files", "*.png")])

# 处理选中的文件
if file_path:
    process_png(file_path)
    print(f"处理完成:{file_path.replace('.png', '_processed.png')}")

print("所有文件处理完成。")

  1. 写一个python脚本,删除rgb为0 0 0的像素,作用与heightmap_origin.png
from tkinter import Tk, filedialog
from PIL import Image
import numpy as np

# 增加 PIL 的图像大小限制
Image.MAX_IMAGE_PIXELS = None

def process_png(input_path):
    # 打开PNG文件
    img = Image.open(input_path)
    img = img.convert("RGBA")
    data = np.array(img)

    # 创建一个布尔掩码,找到需要处理的像素
    mask_black = (data[:, :, :3] == [0, 0, 0]).all(axis=2)

    # 将黑色像素设为透明
    data[mask_black] = [255, 255, 255, 0]

    # 创建处理后的图像
    processed_img = Image.fromarray(data, 'RGBA')
    output_path = input_path.replace(".png", "_processed.png")
    processed_img.save(output_path, "PNG")

# 创建一个Tkinter根窗口并隐藏它
root = Tk()
root.withdraw()

# 打开文件对话框,选择PNG文件
file_path = filedialog.askopenfilename(filetypes=[("PNG files", "*.png")])

# 处理选中的文件
if file_path:
    process_png(file_path)
    print(f"处理完成:{file_path.replace('.png', '_processed.png')}")

print("所有文件处理完成。")

  1. 用gimp打开其中一张处理过的png,点击 文件—>作为图层打开 ,打开其它处理过的png,countries.png要在最下面
  2. 用移动工具移动图层位置,然后裁剪分辨率。我这里使用了PhotoGIMP插件,快捷键和PS一样,原本快捷键是 M 和 shift + c 。
  3. 稍微裁剪一下边边角角,然后为 countries.png 和 origin.png 单独导出。名称随意, 去掉保存背景色 ,勾上保存透明像素的颜色值 ,选择8位RGBA
  4. 写python脚本,合并两张图片,逻辑是合并两张png图片,RGB值相加,透明像素不参与计算,如果最终计算出来的RGB值大于255 255 255,那么就输出为255 255 255,为了提升效率,这里缩放了一半像素
import numpy as np
from PIL import Image
import os
from tkinter import Tk
from tkinter.filedialog import askopenfilename

Image.MAX_IMAGE_PIXELS = None  # 移除限制

def merge_images(image_path1, image_path2, output_path, scale_factor=0.5):
    # 打开两张图片并按比例缩放
    img1 = Image.open(image_path1).convert("RGBA")
    img2 = Image.open(image_path2).convert("RGBA")

    # 缩放图片
    img1 = img1.resize((int(img1.width * scale_factor), int(img1.height * scale_factor)), Image.LANCZOS)
    img2 = img2.resize((int(img2.width * scale_factor), int(img2.height * scale_factor)), Image.LANCZOS)

    # 确保两张图片的尺寸相同
    if img1.size != img2.size:
        raise ValueError("两张图片必须具有相同的尺寸")

    # 将图片转换为numpy数组
    arr1 = np.array(img1)
    arr2 = np.array(img2)

    # 创建一个空的合并数组
    merged_arr = np.zeros_like(arr1)

    # 直接相加RGB通道,并处理溢出
    for i in range(arr1.shape[0]):  # 遍历每一行
        for j in range(arr1.shape[1]):  # 遍历每一列
            r = int(arr1[i, j, 0]) + int(arr2[i, j, 0])
            g = int(arr1[i, j, 1]) + int(arr2[i, j, 1])
            b = int(arr1[i, j, 2]) + int(arr2[i, j, 2])

            # 如果RGB值都大于255,则设置为255 255 255
            if r > 255 and g > 255 and b > 255:
                merged_arr[i, j, :3] = [255, 255, 255]
            else:
                merged_arr[i, j, :3] = [min(r, 255), min(g, 255), min(b, 255)]

    # 合并透明度通道
    merged_arr[:, :, 3] = np.maximum(arr1[:, :, 3], arr2[:, :, 3])  # 透明度可以根据需要进行合并

    # 保存合并后的图片
    Image.fromarray(merged_arr.astype(np.uint8), "RGBA").save(output_path, "PNG")



def main():
    # 创建一个隐藏的Tkinter窗口
    Tk().withdraw()

    # 选择第一张图片
    print("请选择第一张图片...")
    image_path1 = askopenfilename(title="选择第一张图片", filetypes=[("PNG files", "*.png")])
    if not image_path1:
        print("未选择文件,程序结束。")
        return

    # 选择第二张图片
    print("请选择第二张图片...")
    image_path2 = askopenfilename(title="选择第二张图片", filetypes=[("PNG files", "*.png")])
    if not image_path2:
        print("未选择文件,程序结束。")
        return

    # 获取输入文件夹
    input_folder = os.path.dirname(image_path1)

    # 设置输出文件名和路径
    output_filename = "merged_image.png"
    output_path = os.path.join(input_folder, output_filename)

    # 合并图片
    merge_images(image_path1, image_path2, output_path)
    print(f"合并完成,输出文件保存为: {output_path}")

if __name__ == "__main__":
    main()

  1. 合并之后的png导入到GIMP中,右键图层,找到缩放图层,然后在高度宽度任意一个 *2
  2. 选择一个图层,右键合并可见图层,选择裁剪至图像
  3. 删除剩下的两个图层,设置前景色为0 0 0,新建一个海洋图层,填充为前景色,放到最下面,然后合并图层
  4. 裁剪到合适的地方,然后选择 图层—>缩放图像 ,高度选择 4096 ,宽度会跟着变化,中途会有一段时间未响应,等一会就好了。选择 图像—>画布大小 ,宽度填写 8192 ,填充选择透明,然后改变大小。
  5. 新建图层,以0 0 0填充,然后合并图层
  6. 导出为 8位灰阶 ,不保存透明像素的颜色值,创建一个mod,ir启动器属性添加 -mapeditor