--- /dev/null
+
+# -------------------------------------------------------------------
+# 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
+