Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import numpy as np
- import math
- try:
- from PIL import Image # necessary for manipulation with images
- from PIL import ImageFilter
- from PIL import ImageDraw,ImageFont
- except:
- print (" Warning: Failed to load Pillow (Imaging) modules!")
- print (" Pillow (fork of PIL) should be available in repositories")
- print (" of your distribution, please install it first.")
- exit()
- length=2**10 #working size
- rough_intensity=1.5 #1.5 good
- rough_gamma=1.3 #0.85good
- highcropprc=2
- lowcropprc=5 #% water surface effectively
- map_size=384 # final size in widelands
- minavg=0.2
- maxavg=0.45
- seed_intensity=0.15 # 0.66 good, inserting additional randomnes before running diamond square algorithm
- px_array=np.zeros(shape=(length,length),dtype=float)
- blur_array=np.zeros(shape=(length,length),dtype=float)
- def new_RGB(bp1,bp2,value,R1,G1,B1,R2,G2,B2):
- ratio=(float(value)-bp1)/(bp2-bp1)
- Rnew=R1*(1-ratio)+ R2*ratio
- Gnew=G1*(1-ratio)+ G2*ratio
- Bnew=B1*(1-ratio)+ B2*ratio
- return Rnew,Gnew,Bnew
- def wrap(value):
- if value>=length:
- return value-length
- if value<0:
- return value+length
- return value
- k=0
- listofdef=[0,0.1,0.2,0.8,0.9,1]
- while k<10: #generates 10 fractals (=10 jpg images and txt files with heights)
- print ("Fractal: "+str(k+1))
- lowcount=0
- highcount=1
- px_array.fill(-100) #defaults
- px_array[0 , 0]=random.uniform(0,1) #at least one value must be given to start fractal generation
- #this is an exemption to fractal algorithm but we need to add more randomness/irregularity
- for i in range(8):
- for j in range(8):
- if random.uniform(0,1) > (1- seed_intensity):
- i_l=int(i/8.0*length)
- j_l=int(j/8.0*length)
- px_array[i_l, j_l]=random.choice(listofdef)
- sqsize=length
- while sqsize >1:
- roughness=math.pow(rough_intensity*float(sqsize)/length,rough_gamma)
- print (" sqsize: "+str(sqsize)+", roughness: " +str(round(roughness,3)))
- #iterating over line, starting on 0+sqsize/2
- pixel_x_pos=0+sqsize/2
- while pixel_x_pos<length:
- pixel_y_pos=0+sqsize/2
- while pixel_y_pos<length:
- px1= px_array[wrap(pixel_x_pos-sqsize/2) , wrap(pixel_y_pos-sqsize/2)]
- px2= px_array[wrap(pixel_x_pos-sqsize/2) , wrap(pixel_y_pos+sqsize/2)]
- px3= px_array[wrap(pixel_x_pos+sqsize/2) , wrap(pixel_y_pos-sqsize/2)]
- px4= px_array[wrap(pixel_x_pos+sqsize/2) , wrap(pixel_y_pos+sqsize/2)]
- new_value=(px1+px2+px3+px4)/4.0 + random.uniform(-1,1)*roughness
- if new_value>1:
- highcount+=1
- if new_value<0:
- lowcount+=1
- if px1==-100 or px2==-100 or px3==-100 or px4==-100:
- print (" touched wrong pixel: "+str(pixel_x_pos)+" x "+str(pixel_y_pos))
- #exit()
- px_array[pixel_x_pos , pixel_y_pos]=new_value
- pixel_y_pos=pixel_y_pos+sqsize
- pixel_x_pos=pixel_x_pos+sqsize
- #iterating once more and populating not calculated pixels
- pixel_x_pos=0
- while pixel_x_pos<length:
- pixel_y_pos=0
- while pixel_y_pos<length:
- #print (pixel_x_pos,pixel_y_pos)
- if px_array[pixel_x_pos,pixel_y_pos]>-100: #never change yet calculated pixel
- pixel_y_pos=pixel_y_pos+sqsize/2
- continue
- px1= px_array[wrap(pixel_x_pos-sqsize/2) , pixel_y_pos]
- px2= px_array[wrap(pixel_x_pos+sqsize/2) , pixel_y_pos]
- px3= px_array[pixel_x_pos , wrap(pixel_y_pos-sqsize/2)]
- px4= px_array[pixel_x_pos , wrap(pixel_y_pos+sqsize/2)]
- if px1==-100 or px2==-100 or px3==-100 or px4==-100:
- print (" touched wrong pixel: "+str(pixel_x_pos)+" x "+str(pixel_y_pos))
- #exit()
- new_value=(px1+px2+px3+px4)/4.0 + random.uniform(-1,1)*roughness
- if new_value>1:
- highcount+=1
- if new_value<0:
- lowcount+=1
- #print (str(new_value)+" ( pure avg="+str((px1+px2+px3+px4)/4.0)+") on pos :"+str(pixel_x_pos)+" x "+str(pixel_y_pos))
- px_array[pixel_x_pos , pixel_y_pos]=new_value
- pixel_y_pos=pixel_y_pos+sqsize/2
- pixel_x_pos=pixel_x_pos+sqsize/2
- sqsize=sqsize/2
- newImage = Image.new( 'RGB', (length,length), "black")
- #blurring the image
- for i in range(length):
- for j in range(length):
- if px_array[i][j]==-100:
- print ("unpopulated pixel")
- exit()
- blur_array[i,j]=(px_array[i,j] + px_array[i,j] + px_array[wrap(i+1),wrap(j)] +
- px_array[wrap(i-1),wrap(j)] + px_array[wrap(i),wrap(j+1)] + px_array[wrap(i),wrap(j-1)])/ 6.0
- #iteration 2
- for i in range(length):
- for j in range(length):
- px_array[i,j]=(blur_array[i,j] + px_array[i,j] + blur_array[wrap(i+1),wrap(j)] +
- blur_array[wrap(i-1),wrap(j)] + blur_array[wrap(i),wrap(j+1)] + blur_array[wrap(i),wrap(j-1)])/ 6.0
- #iteration 3
- for i in range(length):
- for j in range(length):
- blur_array[i,j]=(px_array[i,j] + px_array[i,j] + px_array[wrap(i+1),wrap(j)] +
- px_array[wrap(i-1),wrap(j)] + px_array[wrap(i),wrap(j+1)] + px_array[wrap(i),wrap(j-1)])/ 6.0
- #iteration 4
- for i in range(length):
- for j in range(length):
- px_array[i,j]=(blur_array[i,j] + px_array[i,j] + blur_array[wrap(i+1),wrap(j)] +
- blur_array[wrap(i-1),wrap(j)] + blur_array[wrap(i),wrap(j+1)] + blur_array[wrap(i),wrap(j-1)])/ 6.0
- #normalizing the image, calculating minvalue and maxvalue
- minvalue=10
- maxvalue=-10
- for i in range(length):
- #print(str(i)+" : "+str(px_array[i]))
- for j in range(length):
- if px_array[i][j]<minvalue:
- minvalue=px_array[i][j]
- elif px_array[i][j]>maxvalue:
- maxvalue=px_array[i][j]
- print (" Raw fractal values range: "+str(round(minvalue,2)) + " - "+ str(round(maxvalue,2))) #+", avg: "+str(avgvaluesum/count))
- #ordering all pixel values
- allpx=[]
- for i in range(0,length,2):
- for j in range(0,length,2):
- allpx.append(px_array[i][j])
- allpx=sorted(allpx)
- lowvalue =allpx[int((lowcropprc/100.0)*len(allpx))] #this and everything below will be water at level 0
- highvalue=allpx[int(((100-highcropprc)/100.0)*len(allpx))] #this and all above will be top on level 60
- print (" Cropping top and bottoms at: "+str(round(lowvalue,2))+ " / "+str(round(highvalue,2)))
- lowcount=0
- hightcount=0
- avgvaluesum=0
- count=0.0
- #recalculating image
- for i in range(length):
- for j in range(length):
- if px_array[i][j]>highvalue:
- highcount+=1
- px_array[i][j]=1
- elif px_array[i][j]<lowvalue:
- lowcount+=1
- px_array[i][j]=0
- else:
- #print (str(px_array[i][j])+ " to")
- px_array[i][j]=(px_array[i][j]-lowvalue)/(highvalue-lowvalue)
- #print (str(px_array[i][j]))
- avgvaluesum+=px_array[i,j] #=math.pow(px_array[i,j],1.3) #gamma
- count+=1
- avg=float(avgvaluesum)/count
- print (" Average of non-limit pixels: "+str(round(avg,3))+", image split: "+str(lowcount) +" / "+str(count)+" / "+str(highcount))
- gamma=1
- avgvaluesum=0
- count=0.0
- if avg<minavg:
- gamma=(avg/minavg)**2
- #applying gamma
- for i in range(length):
- for j in range(length):
- if px_array[i][j]<1 and px_array[i][j]>0:
- px_array[i][j]=pow(px_array[i][j],gamma)
- avgvaluesum=avgvaluesum+px_array[i][j]
- count+=1
- elif avg>maxavg:
- gamma=(avg/maxavg)
- #applying gamma
- for i in range(length):
- for j in range(length):
- if px_array[i][j]<1 and px_array[i][j]>0:
- px_array[i][j]=pow(px_array[i][j],gamma)
- avgvaluesum=avgvaluesum+px_array[i][j]
- count+=1
- if count>0:
- print (" applying gamma: "+ str(round(gamma,2))+"(if needed), new average:"+str(round(float(avgvaluesum)/count,2)))
- #verifying the results the image, calculating minvalue and maxvalue
- minvalue=10
- maxvalue=-10
- for i in range(length):
- #print(str(i)+" : "+str(px_array[i]))
- for j in range(length):
- if px_array[i][j]<minvalue:
- minvalue=px_array[i][j]
- if px_array[i][j]>maxvalue:
- maxvalue=px_array[i][j]
- print (" Modified image value range: "+str(minvalue) + " - "+ str(maxvalue))
- #output as jpg image
- P1R=0 #grass
- P1G=70
- P1B=0
- P2R=61 #light green
- P2G=114
- P2B=61
- P3R=112 #light brown
- P3G=112
- P3B=76
- P4R=56 #dark brown
- P4G=55
- P4B=5
- P5R=210
- P5G=209
- P5B=203
- for i in range(length):
- #print(str(i)+" : "+str(px_array[i]))
- for j in range(length):
- if px_array[i][j]==-100:
- print ("unpopulated pixel")
- exit()
- value=px_array[i][j]*255
- if value<=0:
- finalR=0
- finalG=115
- finalB=232
- elif value<60:
- finalR,finalG,finalB = new_RGB(0,60,value,P1R,P1G,P1B,P2R,P2G,P2B)
- elif value<130:
- finalR,finalG,finalB = new_RGB(60,130,value,P2R,P2G,P2B,P3R,P3G,P3B)
- elif value<215:
- finalR,finalG,finalB = new_RGB(130,215,value,P3R,P3G,P3B,P4R,P4G,P4B)
- else:
- finalR,finalG,finalB = new_RGB(215,255,value,P5R,P5G,P5B,255,255,255)
- newImage.putpixel((i,j),(int(finalR),int(finalG),int(finalB)))
- newname="Terrain_"+str(k+1)+".jpg"
- newImage.save(newname,quality=98)
- #output to file
- filename="import_coordinates_"+str(k+1)+".txt"
- f = open(filename, 'w')
- for i in range(map_size):
- x=round(float(i)/map_size*length)
- #print (" calculating : " +str(i) + "->"+str(x))
- for j in range(map_size):
- offset=0
- if j%2==1:
- offset=0.5
- y=round(float(j+offset)/map_size*length)
- if px_array[x][y]==0:
- value=0
- else:
- value=min ((px_array[x][y]*60.0)+1 , 60)
- value=max(value,0)
- value=int(value)
- f.write(str(i)+" "+str(j)+" "+str(value)+'\n')
- f.write (' \n')
- f.close
- k=k+1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement