2024-12-17 17:21:55 +01:00
|
|
|
|
|
|
|
# -------------------------------------------------------------------
|
|
|
|
# ORTHOGRAPHIC
|
|
|
|
# Your personal aerial satellite. Always on. At any altitude.*
|
|
|
|
# Developed by MarStrMind
|
|
|
|
# License: Open Software License 3.0
|
|
|
|
# Up to date version always on marstr.online
|
|
|
|
# -------------------------------------------------------------------
|
|
|
|
# resourcegen.py
|
|
|
|
# Generates resources from existing material to provide much more
|
|
|
|
# variety than the fixed patch sources.
|
|
|
|
#
|
|
|
|
# We usually pass in 5 numbers, out of 15 possible images. This
|
|
|
|
# gives us a total of 3000+ possible combinations of images, per
|
|
|
|
# OSM tag.
|
|
|
|
# -------------------------------------------------------------------
|
|
|
|
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
from random import randrange
|
|
|
|
import random
|
|
|
|
from PIL import Image, ImageFilter, ImageDraw, ImageChops, ImageEnhance
|
|
|
|
from defines import *
|
|
|
|
from log import *
|
|
|
|
|
|
|
|
class mstr_resourcegen:
|
|
|
|
|
|
|
|
def __init__(self, tag, value, sources):
|
|
|
|
self._sources = sources
|
|
|
|
self._tag = tag
|
|
|
|
self._value = value
|
2024-12-22 12:37:21 +01:00
|
|
|
self._contrast = 1
|
2024-12-17 17:21:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
# Sets the contrast from layergen
|
|
|
|
def setLayerContrast(self, contrast):
|
|
|
|
self._contrast = contrast
|
2024-12-22 12:37:21 +01:00
|
|
|
if contrast == 0: self._contrast = 1
|
2024-12-17 17:21:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
# This generates a resource from the given sources
|
|
|
|
# ResourceGen(tm) technology. Only in Orthographic.
|
|
|
|
def gensource(self):
|
|
|
|
|
|
|
|
# The images to return
|
|
|
|
resources = []
|
|
|
|
|
|
|
|
# The array for the sources
|
|
|
|
sources = self._sources
|
|
|
|
|
|
|
|
num_string = ""
|
|
|
|
for s in range(0, len(sources)):
|
|
|
|
num_string = num_string + str(sources[s])
|
|
|
|
if s < len(sources) - 1:
|
|
|
|
num_string = num_string + "_"
|
|
|
|
|
|
|
|
# File name
|
|
|
|
gensrc_fn = mstr_datafolder + "_cache/_pool/ptc_" + self._tag + "_" + self._value + "_" + num_string + ".png"
|
|
|
|
|
|
|
|
# For equalizing
|
|
|
|
smlsize = 0
|
|
|
|
|
|
|
|
# Load the sources
|
|
|
|
src_img = []
|
|
|
|
for s in range(0, len(sources)):
|
|
|
|
imgfn = mstr_datafolder + "textures/" + self._tag + "/" + self._value + "/" + str(sources[s]) + ".png"
|
|
|
|
img = Image.open(imgfn)
|
|
|
|
if smlsize == 0 or smlsize > img.width:
|
|
|
|
smlsize = img.width
|
|
|
|
src_img.append(img)
|
|
|
|
|
|
|
|
# Generate a resource image
|
|
|
|
gensrc = Image.new("RGBA", (smlsize, smlsize))
|
|
|
|
|
|
|
|
# Pixel access
|
|
|
|
gensrc_p = gensrc.load()
|
|
|
|
|
|
|
|
# Pixel access for the sources
|
|
|
|
src_pix = []
|
|
|
|
for p in range(0, len(sources)):
|
|
|
|
src_pix.append(src_img[p].load())
|
|
|
|
|
|
|
|
# Generate the source
|
|
|
|
for y in range(0, gensrc.height):
|
|
|
|
for x in range(0, gensrc.width):
|
|
|
|
pdata = []
|
|
|
|
for p in range(0, len(sources)):
|
|
|
|
pdata.append(src_pix[p][x,y])
|
|
|
|
|
|
|
|
# Calculate a pixel average
|
|
|
|
avg_r = 0
|
|
|
|
avg_g = 0
|
|
|
|
avg_b = 0
|
|
|
|
avg_a = 0
|
|
|
|
|
|
|
|
for p in range(0, len(sources)):
|
|
|
|
avg_r = avg_r + pdata[p][0]
|
|
|
|
avg_g = avg_g + pdata[p][1]
|
|
|
|
avg_b = avg_b + pdata[p][2]
|
|
|
|
avg_a = avg_a + pdata[p][3]
|
|
|
|
|
|
|
|
avg_r = int( (avg_r / len(sources)) * random.uniform(0.85, 1.01) )
|
|
|
|
avg_g = int( (avg_g / len(sources)) * random.uniform(0.85, 1.01) )
|
|
|
|
avg_b = int( (avg_b / len(sources)) * random.uniform(0.85, 1.01) )
|
|
|
|
#avg_a = 255
|
|
|
|
avg_a = int( (avg_a / len(sources)) * random.uniform(0.85, 1.01) )
|
|
|
|
|
|
|
|
pxcolor = (avg_r, avg_g, avg_b, avg_a)
|
|
|
|
|
|
|
|
gensrc_p[x,y] = pxcolor
|
|
|
|
|
|
|
|
|
|
|
|
# Some features need a bit of contrast to make details visible
|
|
|
|
if (
|
|
|
|
(self._tag == "landuse" and self._value == "forest") or
|
|
|
|
(self._tag == "landuse" and self._value == "meadow") or
|
|
|
|
(self._tag == "landuse" and self._value == "grass") or
|
|
|
|
(self._tag == "leisure" and self._value == "nature_reserve") or
|
|
|
|
(self._tag == "natural" and self._value == "grassland") or
|
|
|
|
(self._tag == "landuse" and self._value == "greenfield") or
|
|
|
|
(self._tag == "natural" and self._value == "heath") or
|
|
|
|
(self._tag == "natural" and self._value == "wetland") or
|
|
|
|
(self._tag == "leisure" and self._value == "park") or
|
|
|
|
(self._tag == "building")
|
|
|
|
):
|
|
|
|
gensrc = ImageEnhance.Contrast(gensrc).enhance(self._contrast)
|
|
|
|
|
|
|
|
|
|
|
|
#gensrc.save(gensrc_fn)
|
|
|
|
resources.append(gensrc)
|
|
|
|
|
|
|
|
|
|
|
|
# We also need to generate a border for the source. For this to work,
|
|
|
|
# we first need to generate an image as we do in layergen
|
|
|
|
border = Image.new("RGBA", (mstr_photores, mstr_photores))
|
|
|
|
|
|
|
|
# Generate the source image
|
|
|
|
for p in range(1, 201):
|
|
|
|
rx = randrange(0-int(gensrc.width/2), border.width - int(gensrc.width/2))
|
|
|
|
ry = randrange(0-int(gensrc.height/2), border.height - int(gensrc.height/2))
|
|
|
|
border.alpha_composite(gensrc, dest=(rx, ry))
|
|
|
|
|
|
|
|
# Make it seamless
|
|
|
|
half_width = int(mstr_photores / 2)
|
|
|
|
half_height = int(mstr_photores / 2)
|
|
|
|
|
|
|
|
img_shifted_x = ImageChops.offset(border, half_width, 0) # Shift horizontally
|
|
|
|
img_shifted_y = ImageChops.offset(border, 0, half_height) # Shift vertically
|
|
|
|
img_shifted_xy = ImageChops.offset(border, half_width, half_height) # Shift diagonally
|
|
|
|
|
|
|
|
img_blend_x = Image.blend(border, img_shifted_x, alpha=0.5)
|
|
|
|
img_blend_y = Image.blend(img_blend_x, img_shifted_y, alpha=0.5)
|
|
|
|
img_blend = Image.blend(img_blend_y, img_shifted_xy, alpha=0.5)
|
|
|
|
|
|
|
|
# Apply the mask
|
|
|
|
brdmsk = Image.open(mstr_datafolder + "textures/brdmsk.png")
|
|
|
|
smlpix = img_blend.load()
|
|
|
|
mskpix = brdmsk.load()
|
|
|
|
for y in range(0, img_blend.height):
|
|
|
|
for x in range(0, img_blend.width):
|
|
|
|
msk = mskpix[x,y]
|
|
|
|
sml = smlpix[x,y]
|
|
|
|
c = (sml[0], sml[1], sml[2], msk[3])
|
|
|
|
smlpix[x,y] = c
|
|
|
|
|
|
|
|
|
|
|
|
# Save the border
|
|
|
|
resources.append(img_blend)
|
|
|
|
#img_blend.save(mstr_datafolder + "_cache/_pool/brd_" + self._tag + "_" + self._value + "_" + num_string + ".png")
|
|
|
|
|
|
|
|
|
|
|
|
# Provide the images
|
|
|
|
return resources
|
|
|
|
|