# ------------------------------------------------------------------- # 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