#!/usr/bin/env python
# random_downtown.py Rel 5
# Created by Tin Tran
# Comments directed to http://gimplearn.net
#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit: http://www.gnu.org/licenses/gpl.html
#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release.
# Rel 2: Try to bypass Certificate Verification Error repoted by Pat625.
# Rel 3: Filled windows.
# Rel 4: Make seamless (requested by lylejk on GIMPCHAT). You just gotta merge all the building layers and then "layer to image size".
# Rel 5: Run different code depending on version 2.8 or 2.10
from gimpfu import *
import random
from gimpfu import *
import re, tempfile
import os
import ssl
#open and write tempf once so that it doesn't make multiple files in document history.
tempf=tempfile.NamedTemporaryFile(mode='w', suffix='.svg', dir=gimp.directory, delete=False)
tempf.write("whatever")
tempf.close()
import urllib2
import ssl
links = ['https://plus.unsplash.com/premium_photo-1676218886284-bca308235404?q=80&w=1936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1726725935085-fbc079dc5557?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1673621329410-e4ef5df05b69?q=80&w=1936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1648714406165-bc37682149cb?q=80&w=1925&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649956736495-5685285a8f9f?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1672663791479-c275b663fd72?q=80&w=1912&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1648618657670-d7d64c5e3ef7?q=80&w=2080&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1698849368937-37dddf9f58f1?q=80&w=1935&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1717489358244-01dd1c704afa?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1680143217012-db17c482ab94?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1673890318279-02d6cf905019?q=80&w=1936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1678904817922-b20be9a075a8?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1685477990878-da34123f5998?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649685819493-e5f3688a7d36?q=80&w=1991&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649372450315-7a69c613fb10?q=80&w=2071&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649972046682-2583cdd9bab8?q=80&w=1950&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1650060165632-82e4f0dacfc0?q=80&w=2112&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1676625176020-3bbb1c0adea1?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649289264155-4404150df2fb?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1647694079696-36fb2f5e337a?q=80&w=1936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1680281937115-c5eca9c68cc1?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649384472975-98ac52a096d7?q=80&w=2127&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649372449815-306c7a9d715b?q=80&w=2018&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649232275731-108ab7eb2a44?q=80&w=1975&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1463130456064-77fda7f96d6b?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1532456745301-b2c645d8b80d?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1649777689218-f5ddf4f69381?q=80&w=1972&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1483959651481-dc75b89291f1?q=80&w=2149&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1676269617127-24352e84349a?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1451755032734-ada8d61ecf2f?q=80&w=2008&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1684311194610-1243fc49cfcb?q=80&w=1930&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1486718448742-163732cd1544?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1488972685288-c3fd157d7c7a?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1494028960909-2321fad2a785?q=80&w=2080&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://plus.unsplash.com/premium_photo-1672265517508-52bbda78e263?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1527831176161-52b74dab16ea?q=80&w=1935&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
'https://images.unsplash.com/photo-1612365009551-0abb42a5f096?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
]
# Create an SSL context (similar to gcontext in Python 2)
# Fetch the file content
def python_random_downtown_tt(image, layer, minWidth, minHeight, maxWidth, maxHeight, numB):
pdb.gimp_image_undo_group_start(image)
pdb.gimp_context_push()
gcontext = ssl._create_unverified_context()
#gcontext = ssl.create_default_context()
# gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
numB = int(numB)
# gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) # Only for gangstars to by pass certifate check found on https://stackoverflow.com/questions/27835619/urllib-and-ssl-certificate-verify-failed-error
for i in range(0,numB):
filecontent = urllib2.urlopen(links[random.randrange(0,len(links))], context=gcontext).read()
#filecontent = urllib.request.urlopen(url, context=gcontext).read()
#filecontent = urllib2.urlopen('https://unsplash.it/1600/1200/?random', context=gcontext).read()
f = open(tempf.name,"wb")
f.write(filecontent)
f.close();
#urllib.urlretrieve("https://unsplash.it/1600/1200/?random",tempf.name)
random_image = pdb.file_jpeg_load(tempf.name,tempf.name)
random_layer = pdb.gimp_image_get_active_layer(random_image)
#pdb.gimp_display_new(random_image)
active_layer = pdb.gimp_image_get_active_layer(random_image)
bwidth = random.randrange(minWidth,maxWidth+1) #building width random between min and max width
bheight = random.randrange(minHeight,maxHeight+1) #building height random between min and max width
x = random.randrange(0,1600-bwidth+1) #top left corner of building location x
y = random.randrange(0,1200-bheight+1) #top left corner of building location y
#copy step which creates building look
pdb.gimp_image_select_rectangle(random_image,CHANNEL_OP_REPLACE,x,y,bwidth,bheight)
btype = random.randrange(0,3)
innerwidth = bwidth * 9.0/10.0
innerheight = bheight * 9.0/10.0
startx = (bwidth-innerwidth)/2.0
starty = (bheight-innerheight)/2.0
if btype == 0: #do horizontal windows
num_rows = random.randrange(8,16)*4+3; #number of rows.
row_height = innerheight*1.0/num_rows*4;
win_height = innerheight*1.0/num_rows*3;
for j in range(1,num_rows+1):
if (j%4)==3: #if odd we deselect it
wx = x+startx
wy = y+starty + (j/4) * row_height
pdb.gimp_image_select_rectangle(random_image,CHANNEL_OP_SUBTRACT,wx,wy,innerwidth,win_height)
elif btype == 1: #do vertical windows
num_cols = random.randrange(5,10)*4+3; #number of cols
col_width = innerwidth*1.0/num_cols*4;
win_width = innerwidth*1.0/num_cols*3;
for k in range(1,num_cols+1):
if (k%4)==3: #if odd we deselect it
wx = x+startx + (k/4) * col_width
wy = y+starty
pdb.gimp_image_select_rectangle(random_image,CHANNEL_OP_SUBTRACT,wx,wy,win_width,innerheight)
elif btype == 2: #do actual windows
num_rows = random.randrange(8,16)*4+3; #number of rows.
row_height = innerheight*1.0/num_rows*4;
win_height = innerheight*1.0/num_rows*3;
num_cols = random.randrange(5,10)*4+3; #number of cols.
col_width = innerwidth*1.0/num_cols*4;
win_width = innerwidth*1.0/num_cols*3;
for j in range(1,num_rows+1):
if (j%4)==3: #if odd we deselect it
for k in range(1,num_cols+1):
if (k%4)==3: #if odd we deselect it
wx = x+startx + (k/4) * col_width
wy = y+starty + (j/4) * row_height
pdb.gimp_image_select_rectangle(random_image,CHANNEL_OP_SUBTRACT,wx,wy,win_width,win_height)
pdb.gimp_edit_copy(active_layer)
floating_sel = pdb.gimp_edit_paste(layer,True)
pdb.gimp_floating_sel_to_layer(floating_sel)
y_offset = layer.height*2.0/3.0 - bheight
x_offset = random.randrange(0,layer.width+1)
pdb.gimp_layer_set_offsets(floating_sel,x_offset,y_offset)
#create seamless
gimp_version = pdb.gimp_version() #GET GIMP VERSION
if x_offset > (layer.width - bwidth): #if it pops out on the right side.
floating_sel = pdb.gimp_edit_paste(layer,True)
pdb.gimp_floating_sel_to_layer(floating_sel)
right_x_offset = x_offset - layer.width #make a copy on the left side so that it's seamless
pdb.gimp_layer_set_offsets(floating_sel,right_x_offset,y_offset)
if gimp_version.startswith("2.8"):
result = image.layers[0]
result = pdb.gimp_image_merge_down(image,result,EXPAND_AS_NECESSARY)
#do it again so it's filled windows.
x = random.randrange(0,1600-bwidth+1) #top left corner of building location x
y = random.randrange(0,1200-bheight+1) #top left corner of building location y
pdb.gimp_image_select_rectangle(random_image,CHANNEL_OP_REPLACE,x,y,bwidth,bheight)
pdb.gimp_edit_copy(active_layer)
floating_sel = pdb.gimp_edit_paste(layer,True)
pdb.gimp_floating_sel_to_layer(floating_sel)
pdb.gimp_layer_set_offsets(floating_sel,x_offset,y_offset)
if gimp_version.startswith("2.8"):
pdb.gimp_brightness_contrast(floating_sel,int(-0.45*127),0)
elif gimp_version.startswith("2.10"):
pdb.gimp_drawable_brightness_contrast(floating_sel,-0.45,0)
#create seamless
result = floating_sel
if x_offset > (layer.width - bwidth): #if it pops out on the right side.
floating_sel = pdb.gimp_edit_paste(layer,True)
pdb.gimp_floating_sel_to_layer(floating_sel)
right_x_offset = x_offset - layer.width #make a copy on the left side so that it's seamless
pdb.gimp_layer_set_offsets(floating_sel,right_x_offset,y_offset)
if gimp_version.startswith("2.8"):
pdb.gimp_brightness_contrast(floating_sel,int(-0.45*127),0)
elif gimp_version.startswith("2.10"):
pdb.gimp_drawable_brightness_contrast(floating_sel,-0.45,0)
if gimp_version.startswith("2.8"):
result = image.layers[0]
result = pdb.gimp_image_merge_down(image,result,EXPAND_AS_NECESSARY)
if gimp_version.startswith("2.8"):
result = image.layers[0]
pdb.gimp_image_lower_item(image,result)
pdb.gimp_image_delete(random_image)
#pdb.gimp_progress_init("Processing...",None)
#pdb.gimp_progress_update(float(intensity)/255.0)
pdb.gimp_context_pop()
pdb.gimp_image_undo_group_end(image)
pdb.gimp_displays_flush()
register(
"python_fu_random_downtown_tt",
"Creates Random Downtown Collage",
"Creates Random Downtown Collage",
"Tin Tran",
"Tin Tran",
"August 2018",
"<Image>/Python-Fu/Random Downtown...", #Menu path
"RGB*, GRAY*",
[
(PF_SPINNER, "minWidth", "Smallest Building Width:", 100, (10, 2000, 1)),
(PF_SPINNER, "minHeight", "Smallest Building Height:", 200, (10, 2000, 1)),
(PF_SPINNER, "maxWidth", "Largest Building Width:", 200, (10, 2000, 1)),
(PF_SPINNER, "maxHeight", "Largest Building Height:", 400, (10, 2000, 1)),
(PF_SPINNER, "numB", "Number of Buildings to Generate:", 20, (1, 500, 1)),
#(PF_GRADIENT, "gradient", "Background Gradient:", 0),
#(PF_TOGGLE, "reverse", "Reverse Gradient:", 0),
#(PF_SPINNER, "slice_angle", "Rotate angle(before slicing):", -5, (-180, 180, 1)),
#(PF_SPINNER, "slice_shift", "Slice Shift(pixels):", -30, (-100, 100, 1)),
#(PF_SPINNER, "text_angle", "Rotate angle(when complete):", -8, (-180, 180, 1)),
],
[],
python_random_downtown_tt)
main()