orthographic/resourcegen.py

174 lines
6.1 KiB
Python
Raw Normal View History

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
self._contrast = 0
# Sets the contrast from layergen
def setLayerContrast(self, contrast):
self._contrast = contrast
# 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