mirror of
https://github.com/Sygil-Dev/sygil-webui.git
synced 2024-12-14 22:13:41 +03:00
Added option to make the grid format the same as the individual image format. There is a new option called grid quality now that allow you to specify on the settings page the quality for the grid image. (#1584)
-Added option to make the grid format the same as the individual image format. There is a new option called grid quality now that allow you to specify on the settings page the quality for the grid image. - Improved the img2txt tab by having more tags.
This commit is contained in:
commit
87a7f5118b
@ -34,7 +34,6 @@ maxMessageSize = 200
|
||||
enableWebsocketCompression = false
|
||||
|
||||
[browser]
|
||||
serverAddress = "localhost"
|
||||
gatherUsageStats = false
|
||||
serverPort = 8501
|
||||
|
||||
|
@ -51,7 +51,7 @@ general:
|
||||
save_format: "png"
|
||||
skip_grid: False
|
||||
skip_save: False
|
||||
grid_format: "jpg:95"
|
||||
grid_quality: 95
|
||||
n_rows: -1
|
||||
no_verify_input: False
|
||||
no_half: False
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
65748
data/img2txt/flavors.txt
65748
data/img2txt/flavors.txt
File diff suppressed because it is too large
Load Diff
160
data/img2txt/subreddits.txt
Normal file
160
data/img2txt/subreddits.txt
Normal file
@ -0,0 +1,160 @@
|
||||
/r/ImaginaryAetherpunk
|
||||
/r/ImaginaryAgriculture
|
||||
/r/ImaginaryAirships
|
||||
/r/ImaginaryAliens
|
||||
/r/ImaginaryAngels
|
||||
/r/ImaginaryAnimals
|
||||
/r/ImaginaryArchers
|
||||
/r/ImaginaryArchitecture
|
||||
/r/ImaginaryArmor
|
||||
/r/ImaginaryArtisans
|
||||
/r/ImaginaryAssassins
|
||||
/r/ImaginaryAstronauts
|
||||
/r/ImaginaryAsylums
|
||||
/r/ImaginaryAutumnscapes
|
||||
/r/ImaginaryAviation
|
||||
/r/ImaginaryAzeroth
|
||||
/r/ImaginaryBattlefields
|
||||
/r/ImaginaryBeasts
|
||||
/r/ImaginaryBehemoths
|
||||
/r/ImaginaryBodyscapes
|
||||
/r/ImaginaryBooks
|
||||
/r/ImaginaryCanyons
|
||||
/r/ImaginaryCarnage
|
||||
/r/ImaginaryCastles
|
||||
/r/ImaginaryCaves
|
||||
/r/ImaginaryCentaurs
|
||||
/r/ImaginaryCharacters
|
||||
/r/ImaginaryCityscapes
|
||||
/r/ImaginaryClerics
|
||||
/r/ImaginaryCowboys
|
||||
/r/ImaginaryCrawlers
|
||||
/r/ImaginaryCultists
|
||||
/r/ImaginaryCybernetics
|
||||
/r/ImaginaryCyberpunk
|
||||
/r/ImaginaryDarkSouls
|
||||
/r/ImaginaryDemons
|
||||
/r/ImaginaryDerelicts
|
||||
/r/ImaginaryDeserts
|
||||
/r/ImaginaryDieselpunk
|
||||
/r/ImaginaryDinosaurs
|
||||
/r/ImaginaryDragons
|
||||
/r/ImaginaryDruids
|
||||
/r/ImaginaryDwarves
|
||||
/r/ImaginaryDwellings
|
||||
/r/ImaginaryElementals
|
||||
/r/ImaginaryElves
|
||||
/r/ImaginaryExplosions
|
||||
/r/ImaginaryFactories
|
||||
/r/ImaginaryFaeries
|
||||
/r/ImaginaryFallout
|
||||
/r/ImaginaryFamilies
|
||||
/r/ImaginaryFashion
|
||||
/r/ImaginaryFood
|
||||
/r/ImaginaryForests
|
||||
/r/ImaginaryFutureWar
|
||||
/r/ImaginaryFuturism
|
||||
/r/ImaginaryGardens
|
||||
/r/ImaginaryGatherings
|
||||
/r/ImaginaryGiants
|
||||
/r/ImaginaryGlaciers
|
||||
/r/ImaginaryGnomes
|
||||
/r/ImaginaryGoblins
|
||||
/r/ImaginaryHellscapes
|
||||
/r/ImaginaryHistory
|
||||
/r/ImaginaryHorrors
|
||||
/r/ImaginaryHumans
|
||||
/r/ImaginaryHybrids
|
||||
/r/ImaginaryIcons
|
||||
/r/ImaginaryImmortals
|
||||
/r/ImaginaryInteriors
|
||||
/r/ImaginaryIslands
|
||||
/r/ImaginaryJedi
|
||||
/r/ImaginaryKanto
|
||||
/r/ImaginaryKnights
|
||||
/r/ImaginaryLakes
|
||||
/r/ImaginaryLandscapes
|
||||
/r/ImaginaryLesbians
|
||||
/r/ImaginaryLeviathans
|
||||
/r/ImaginaryLovers
|
||||
/r/ImaginaryMarvel
|
||||
/r/ImaginaryMeIRL
|
||||
/r/ImaginaryMechs
|
||||
/r/ImaginaryMen
|
||||
/r/ImaginaryMerchants
|
||||
/r/ImaginaryMerfolk
|
||||
/r/ImaginaryMiddleEarth
|
||||
/r/ImaginaryMindscapes
|
||||
/r/ImaginaryMonsterBoys
|
||||
/r/ImaginaryMonsterGirls
|
||||
/r/ImaginaryMonsters
|
||||
/r/ImaginaryMonuments
|
||||
/r/ImaginaryMountains
|
||||
/r/ImaginaryMovies
|
||||
/r/ImaginaryMythology
|
||||
/r/ImaginaryNatives
|
||||
/r/ImaginaryNecronomicon
|
||||
/r/ImaginaryNightscapes
|
||||
/r/ImaginaryNinjas
|
||||
/r/ImaginaryNobles
|
||||
/r/ImaginaryNomads
|
||||
/r/ImaginaryOrcs
|
||||
/r/ImaginaryPathways
|
||||
/r/ImaginaryPirates
|
||||
/r/ImaginaryPolice
|
||||
/r/ImaginaryPolitics
|
||||
/r/ImaginaryPortals
|
||||
/r/ImaginaryPrisons
|
||||
/r/ImaginaryPropaganda
|
||||
/r/ImaginaryRivers
|
||||
/r/ImaginaryRobotics
|
||||
/r/ImaginaryRuins
|
||||
/r/ImaginaryScholars
|
||||
/r/ImaginaryScience
|
||||
/r/ImaginarySeascapes
|
||||
/r/ImaginarySkyscapes
|
||||
/r/ImaginarySlavery
|
||||
/r/ImaginarySoldiers
|
||||
/r/ImaginarySpirits
|
||||
/r/ImaginarySports
|
||||
/r/ImaginarySpringscapes
|
||||
/r/ImaginaryStarscapes
|
||||
/r/ImaginaryStarships
|
||||
/r/ImaginaryStatues
|
||||
/r/ImaginarySteampunk
|
||||
/r/ImaginarySummerscapes
|
||||
/r/ImaginarySwamps
|
||||
/r/ImaginaryTamriel
|
||||
/r/ImaginaryTaverns
|
||||
/r/ImaginaryTechnology
|
||||
/r/ImaginaryTemples
|
||||
/r/ImaginaryTowers
|
||||
/r/ImaginaryTrees
|
||||
/r/ImaginaryTrolls
|
||||
/r/ImaginaryUndead
|
||||
/r/ImaginaryUnicorns
|
||||
/r/ImaginaryVampires
|
||||
/r/ImaginaryVehicles
|
||||
/r/ImaginaryVessels
|
||||
/r/ImaginaryVikings
|
||||
/r/ImaginaryVillages
|
||||
/r/ImaginaryVolcanoes
|
||||
/r/ImaginaryWTF
|
||||
/r/ImaginaryWalls
|
||||
/r/ImaginaryWarhammer
|
||||
/r/ImaginaryWarriors
|
||||
/r/ImaginaryWarships
|
||||
/r/ImaginaryWastelands
|
||||
/r/ImaginaryWaterfalls
|
||||
/r/ImaginaryWaterscapes
|
||||
/r/ImaginaryWeaponry
|
||||
/r/ImaginaryWeather
|
||||
/r/ImaginaryWerewolves
|
||||
/r/ImaginaryWesteros
|
||||
/r/ImaginaryWildlands
|
||||
/r/ImaginaryWinterscapes
|
||||
/r/ImaginaryWitcher
|
||||
/r/ImaginaryWitches
|
||||
/r/ImaginaryWizards
|
||||
/r/ImaginaryWorldEaters
|
||||
/r/ImaginaryWorlds
|
1936
data/img2txt/tags.txt
Normal file
1936
data/img2txt/tags.txt
Normal file
File diff suppressed because it is too large
Load Diff
63
data/img2txt/techniques.txt
Normal file
63
data/img2txt/techniques.txt
Normal file
@ -0,0 +1,63 @@
|
||||
Fine Art
|
||||
Diagrammatic
|
||||
Geometric
|
||||
Architectural
|
||||
Analytic
|
||||
3D
|
||||
Anamorphic
|
||||
Pencil
|
||||
Color Pencil
|
||||
Charcoal
|
||||
Graphite
|
||||
Chalk
|
||||
Pen
|
||||
Ink
|
||||
Crayon
|
||||
Pastel
|
||||
Sand
|
||||
Beach Art
|
||||
Rangoli
|
||||
Mehndi
|
||||
Flower
|
||||
Food Art
|
||||
Tattoo
|
||||
Digital
|
||||
Pixel
|
||||
Embroidery
|
||||
Line
|
||||
Pointillism
|
||||
Single Color
|
||||
Stippling
|
||||
Contour
|
||||
Hatching
|
||||
Scumbling
|
||||
Scribble
|
||||
Geometric Portait
|
||||
Triangulation
|
||||
Caricature
|
||||
Photorealism
|
||||
Photo realistic
|
||||
Doodling
|
||||
Wordtoons
|
||||
Cartoon
|
||||
Anime
|
||||
Manga
|
||||
Graffiti
|
||||
Typography
|
||||
Calligraphy
|
||||
Mosaic
|
||||
Figurative
|
||||
Anatomy
|
||||
Life
|
||||
Still life
|
||||
Portrait
|
||||
Landscape
|
||||
Perspective
|
||||
Funny
|
||||
Surreal
|
||||
Wall Mural
|
||||
Street
|
||||
Realistic
|
||||
Photo Realistic
|
||||
Hyper Realistic
|
||||
Doodle
|
@ -181,15 +181,17 @@ def layout():
|
||||
|
||||
st.session_state["defaults"].general.save_metadata = st.checkbox("Save Metadata", value=st.session_state['defaults'].general.save_metadata,
|
||||
help="Save metadata on the output image. Default: True")
|
||||
save_format_list = ["png"]
|
||||
save_format_list = ["png","jpg", "jpeg","webp"]
|
||||
st.session_state["defaults"].general.save_format = st.selectbox("Save Format", save_format_list, index=save_format_list.index(st.session_state['defaults'].general.save_format),
|
||||
help="Format that will be used whens saving the output images. Default: 'png'")
|
||||
|
||||
st.session_state["defaults"].general.skip_grid = st.checkbox("Skip Grid", value=st.session_state['defaults'].general.skip_grid,
|
||||
help="Skip saving the grid output image. Default: False")
|
||||
if not st.session_state["defaults"].general.skip_grid:
|
||||
st.session_state["defaults"].general.grid_format = st.text_input("Grid Format", value=st.session_state['defaults'].general.grid_format,
|
||||
help="Format for saving the grid output image. Default: 'jpg:95'")
|
||||
|
||||
|
||||
st.session_state["defaults"].general.grid_quality = st.number_input("Grid Quality", value=st.session_state['defaults'].general.grid_quality,
|
||||
help="Format for saving the grid output image. Default: 95")
|
||||
|
||||
st.session_state["defaults"].general.skip_save = st.checkbox("Skip Save", value=st.session_state['defaults'].general.skip_save,
|
||||
help="Skip saving the output image. Default: False")
|
||||
|
@ -92,56 +92,6 @@ def load_blip_model():
|
||||
|
||||
#return server_state["blip_model"]
|
||||
|
||||
|
||||
#
|
||||
def artstation_links():
|
||||
"""Find and save every artstation link for the first 500 pages of the explore page."""
|
||||
# collecting links to the list()
|
||||
links = []
|
||||
|
||||
with open('data/img2txt/artstation_links.txt', 'w') as f:
|
||||
for page_num in range(1,500):
|
||||
response = requests.get(f'https://www.artstation.com/api/v2/community/explore/projects/trending.json?page={page_num}&dimension=all&per_page=100').text
|
||||
# open json response
|
||||
data = json.loads(response)
|
||||
|
||||
# loopinh through json response
|
||||
for result in data['data']:
|
||||
# still looping and grabbing url's
|
||||
url = result['url']
|
||||
links.append(url)
|
||||
# writing each link on the new line (\n)
|
||||
f.write(f'{url}\n')
|
||||
return links
|
||||
#
|
||||
def artstation_users():
|
||||
"""Get all the usernames and full name of the users on the first 500 pages of artstation explore page."""
|
||||
# collect username and full name
|
||||
artists = []
|
||||
|
||||
# opening a .txt file
|
||||
with open('data/img2txt/artstation_artists.txt', 'w') as f:
|
||||
for page_num in range(1,500):
|
||||
response = requests.get(f'https://www.artstation.com/api/v2/community/explore/projects/trending.json?page={page_num}&dimension=all&per_page=100').text
|
||||
# open json response
|
||||
data = json.loads(response)
|
||||
|
||||
|
||||
# loopinh through json response
|
||||
for item in data['data']:
|
||||
#print (item['user'])
|
||||
username = item['user']['username']
|
||||
full_name = item['user']['full_name']
|
||||
|
||||
# still looping and grabbing url's
|
||||
artists.append(username)
|
||||
artists.append(full_name)
|
||||
# writing each link on the new line (\n)
|
||||
f.write(f'{slugify(username)}\n')
|
||||
f.write(f'{slugify(full_name)}\n')
|
||||
|
||||
return artists
|
||||
|
||||
def generate_caption(pil_image):
|
||||
|
||||
load_blip_model()
|
||||
@ -185,6 +135,10 @@ def clear_cuda():
|
||||
|
||||
|
||||
def batch_rank(model, image_features, text_array, batch_size=st.session_state["defaults"].img2txt.batch_size):
|
||||
#logger.info("Ranking")
|
||||
#st.session_state["log"].append("Ranking")
|
||||
#st.session_state["log_message"].code('\n'.join(st.session_state["log"]), language='')
|
||||
|
||||
batch_size = min(batch_size, len(text_array))
|
||||
batch_count = int(len(text_array) / batch_size)
|
||||
batches = [text_array[i*batch_size:(i+1)*batch_size] for i in range(batch_count)]
|
||||
@ -216,7 +170,7 @@ def interrogate(image, models):
|
||||
return
|
||||
|
||||
table = []
|
||||
bests = [[('', 0)]]*5
|
||||
bests = [[('', 0)]]*7
|
||||
|
||||
logger.info("Ranking Text")
|
||||
|
||||
@ -269,9 +223,13 @@ def interrogate(image, models):
|
||||
ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["trending_list"]))
|
||||
ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["movements"]))
|
||||
ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["flavors"]))
|
||||
#ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["domains"]))
|
||||
#ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["subreddits"]))
|
||||
ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["techniques"]))
|
||||
ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["tags"]))
|
||||
|
||||
# ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["genres"]))
|
||||
# ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["styles"]))
|
||||
# ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["techniques"]))
|
||||
# ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["subjects"]))
|
||||
# ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["colors"]))
|
||||
# ranks.append(batch_rank(server_state["clip_models"][model_name], image_features, server_state["moods"]))
|
||||
@ -300,7 +258,7 @@ def interrogate(image, models):
|
||||
|
||||
# for i in range(len(st.session_state["uploaded_image"])):
|
||||
st.session_state["prediction_table"][st.session_state["processed_image_count"]].dataframe(pd.DataFrame(
|
||||
table, columns=["Model", "Medium", "Artist", "Trending", "Movement", "Flavors"]))
|
||||
table, columns=["Model", "Medium", "Artist", "Trending", "Movement", "Flavors", "Techniques", "Tags"]))
|
||||
|
||||
flaves = ', '.join([f"{x[0]}" for x in bests[4]])
|
||||
medium = bests[0][0][0]
|
||||
@ -329,9 +287,12 @@ def img2txt():
|
||||
server_state["mediums"] = load_list(os.path.join(data_path, 'img2txt', 'mediums.txt'))
|
||||
server_state["movements"] = load_list(os.path.join(data_path, 'img2txt', 'movements.txt'))
|
||||
server_state["sites"] = load_list(os.path.join(data_path, 'img2txt', 'sites.txt'))
|
||||
# server_state["genres"] = load_list(os.path.join(data_path, 'img2txt', 'genres.txt'))
|
||||
#server_state["domains"] = load_list(os.path.join(data_path, 'img2txt', 'domains.txt'))
|
||||
#server_state["subreddits"] = load_list(os.path.join(data_path, 'img2txt', 'subreddits.txt'))
|
||||
server_state["techniques"] = load_list(os.path.join(data_path, 'img2txt', 'techniques.txt'))
|
||||
server_state["tags"] = load_list(os.path.join(data_path, 'img2txt', 'tags.txt'))
|
||||
#server_state["genres"] = load_list(os.path.join(data_path, 'img2txt', 'genres.txt'))
|
||||
# server_state["styles"] = load_list(os.path.join(data_path, 'img2txt', 'styles.txt'))
|
||||
# server_state["techniques"] = load_list(os.path.join(data_path, 'img2txt', 'techniques.txt'))
|
||||
# server_state["subjects"] = load_list(os.path.join(data_path, 'img2txt', 'subjects.txt'))
|
||||
|
||||
server_state["trending_list"] = [site for site in server_state["sites"]]
|
||||
@ -402,7 +363,7 @@ def layout():
|
||||
#url = st.text_area("Input Text","")
|
||||
#url = st.text_input("Input Text","", placeholder="A corgi wearing a top hat as an oil painting.")
|
||||
#st.subheader("Input Image")
|
||||
st.session_state["uploaded_image"] = st.file_uploader('Input Image', type=['png', 'jpg', 'jpeg'], accept_multiple_files=True)
|
||||
st.session_state["uploaded_image"] = st.file_uploader('Input Image', type=['png', 'jpg', 'jpeg', 'jfif'], accept_multiple_files=True)
|
||||
|
||||
with st.expander("CLIP models", expanded=True):
|
||||
st.session_state["ViT-L/14"] = st.checkbox("ViT-L/14", value=True, help="ViT-L/14 model.")
|
||||
|
@ -1,4 +1,4 @@
|
||||
# This file is part of stable-diffusion-webui (https://github.com/Sygil-Dev/sygil-webui/).
|
||||
# This file is part of sygil-webui (https://github.com/Sygil-Dev/sygil-webui/).
|
||||
|
||||
# Copyright 2022 Sygil-Dev team.
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@ -171,38 +171,38 @@ load_configs()
|
||||
#else:
|
||||
#app = None
|
||||
|
||||
# should and will be moved to a settings menu in the UI at some point
|
||||
grid_format = [s.lower() for s in st.session_state["defaults"].general.grid_format.split(':')]
|
||||
#
|
||||
grid_format = st.session_state["defaults"].general.save_format
|
||||
grid_lossless = False
|
||||
grid_quality = 100
|
||||
if grid_format[0] == 'png':
|
||||
grid_quality = st.session_state["defaults"].general.grid_quality
|
||||
if grid_format == 'png':
|
||||
grid_ext = 'png'
|
||||
grid_format = 'png'
|
||||
elif grid_format[0] in ['jpg', 'jpeg']:
|
||||
grid_quality = int(grid_format[1]) if len(grid_format) > 1 else 100
|
||||
elif grid_format in ['jpg', 'jpeg']:
|
||||
grid_quality = int(grid_format) if len(grid_format) > 1 else 100
|
||||
grid_ext = 'jpg'
|
||||
grid_format = 'jpeg'
|
||||
elif grid_format[0] == 'webp':
|
||||
grid_quality = int(grid_format[1]) if len(grid_format) > 1 else 100
|
||||
grid_quality = int(grid_format) if len(grid_format) > 1 else 100
|
||||
grid_ext = 'webp'
|
||||
grid_format = 'webp'
|
||||
if grid_quality < 0: # e.g. webp:-100 for lossless mode
|
||||
grid_lossless = True
|
||||
grid_quality = abs(grid_quality)
|
||||
|
||||
# should and will be moved to a settings menu in the UI at some point
|
||||
save_format = [s.lower() for s in st.session_state["defaults"].general.save_format.split(':')]
|
||||
#
|
||||
save_format = st.session_state["defaults"].general.save_format
|
||||
save_lossless = False
|
||||
save_quality = 100
|
||||
if save_format[0] == 'png':
|
||||
if save_format == 'png':
|
||||
save_ext = 'png'
|
||||
save_format = 'png'
|
||||
elif save_format[0] in ['jpg', 'jpeg']:
|
||||
save_quality = int(save_format[1]) if len(save_format) > 1 else 100
|
||||
elif save_format in ['jpg', 'jpeg']:
|
||||
save_quality = int(save_format) if len(save_format) > 1 else 100
|
||||
save_ext = 'jpg'
|
||||
save_format = 'jpeg'
|
||||
elif save_format[0] == 'webp':
|
||||
save_quality = int(save_format[1]) if len(save_format) > 1 else 100
|
||||
elif save_format == 'webp':
|
||||
save_quality = int(save_format) if len(save_format) > 1 else 100
|
||||
save_ext = 'webp'
|
||||
save_format = 'webp'
|
||||
if save_quality < 0: # e.g. webp:-100 for lossless mode
|
||||
@ -2327,7 +2327,7 @@ def process_images(
|
||||
full_path = os.path.join(os.getcwd(), sample_path, sanitized_prompt)
|
||||
|
||||
|
||||
sanitized_prompt = sanitized_prompt[:200-len(full_path)]
|
||||
sanitized_prompt = sanitized_prompt[:120-len(full_path)]
|
||||
sample_path_i = os.path.join(sample_path, sanitized_prompt)
|
||||
|
||||
#print(f"output folder length: {len(os.path.join(os.getcwd(), sample_path_i))}")
|
||||
@ -2340,7 +2340,7 @@ def process_images(
|
||||
full_path = os.path.join(os.getcwd(), sample_path)
|
||||
sample_path_i = sample_path
|
||||
base_count = get_next_sequence_number(sample_path_i)
|
||||
filename = f"{base_count:05}-{steps}_{sampler_name}_{seeds[i]}_{sanitized_prompt}"[:200-len(full_path)] #same as before
|
||||
filename = f"{base_count:05}-{steps}_{sampler_name}_{seeds[i]}_{sanitized_prompt}"[:120-len(full_path)] #same as before
|
||||
|
||||
x_sample = 255. * rearrange(x_sample.cpu().numpy(), 'c h w -> h w c')
|
||||
x_sample = x_sample.astype(np.uint8)
|
||||
@ -2593,7 +2593,7 @@ def process_images(
|
||||
output_images.insert(0, grid)
|
||||
|
||||
grid_count = get_next_sequence_number(outpath, 'grid-')
|
||||
grid_file = f"grid-{grid_count:05}-{seed}_{slugify(prompts[i].replace(' ', '_')[:200-len(full_path)])}.{grid_ext}"
|
||||
grid_file = f"grid-{grid_count:05}-{seed}_{slugify(prompts[i].replace(' ', '_')[:120-len(full_path)])}.{grid_ext}"
|
||||
grid.save(os.path.join(outpath, grid_file), grid_format, quality=grid_quality, lossless=grid_lossless, optimize=True)
|
||||
|
||||
toc = time.time()
|
||||
|
Loading…
Reference in New Issue
Block a user