🧬 Animated Beings
1Explore carousels for various living categories below. Each section features interactive image selectors built using Dash.¶
1.1Human Carousel¶
Source
from dash import Dash, dcc, html, Input, Output, State, ctx
from jupyter_dash import JupyterDash
import os
from IPython.display import clear_output
# Base URL for images on GitHub
RAW_GITHUB = "https://raw.githubusercontent.com/SaraBarbu/Images10k-compendium/main/assets_github/human"
# Face specific categories
FACE_SEX = ["female", "male"]
FACE_AGES = ["baby", "child", "adolescent", "adult", "elder"]
# List of parts (based on repo structure)
HUMAN_PARTS = sorted([
"arm", "ear", "eye", "face", "foot", "hair",
"hand", "leg", "mouth", "nose", "tongue", "tooth"
])
# Local path for file discovery
LOCAL_HUMAN_DIR = os.path.abspath("../assets_github/human")
# Load non-face images
basic_images = {}
for part in HUMAN_PARTS:
if part == "face":
continue
local_folder = os.path.join(LOCAL_HUMAN_DIR, part)
if os.path.isdir(local_folder):
basic_images[part] = sorted([
f"{RAW_GITHUB}/{part}/{img}"
for img in os.listdir(local_folder)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
])
# Load face images
face_images = {}
for sex in FACE_SEX:
for age in FACE_AGES:
local_folder = os.path.join(LOCAL_HUMAN_DIR, "face", sex, age)
if os.path.isdir(local_folder):
face_images[(sex, age)] = sorted([
f"{RAW_GITHUB}/face/{sex}/{age}/{img}"
for img in os.listdir(local_folder)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
])
# Dash app setup
app = JupyterDash(__name__)
app.title = "🧍 Human Carousel"
app.layout = html.Div([
html.H2("🧍 Human Carousel", style={
"textAlign": "center", "marginBottom": "25px", "marginTop": "10px",
"fontSize": "24px", "fontWeight": "bold", "fontFamily": "Georgia, serif"
}),
html.Div([
html.Label("Select body part:", style={
"fontWeight": "normal", "display": "block", "marginBottom": "6px",
"fontSize": "15px", "fontFamily": "Georgia, serif"
}),
dcc.Dropdown(
id='part-dropdown',
options=[{"label": part.capitalize(), "value": part} for part in HUMAN_PARTS],
value=HUMAN_PARTS[0],
clearable=False,
style={"width": "300px", "margin": "0 auto"}
)
], style={"textAlign": "center", "marginBottom": "20px"}),
html.Div(id='sub-dropdowns', style={"textAlign": "center", "marginBottom": "20px"}),
html.Div(id='carousel-container', style={"textAlign": "center"})
])
# Show sex/age dropdowns if 'face'
@app.callback(
Output('sub-dropdowns', 'children'),
Input('part-dropdown', 'value')
)
def update_sub_dropdowns(part):
if part == "face":
return html.Div([
html.Label("Sex:", style={"marginBottom": "6px", "display": "block"}),
dcc.Dropdown(
id='sex-dropdown',
options=[{"label": s.capitalize(), "value": s} for s in FACE_SEX],
value=FACE_SEX[0],
clearable=False,
style={"width": "200px", "margin": "0 auto 12px auto"}
),
html.Label("Age group:", style={"marginBottom": "6px", "display": "block"}),
dcc.Dropdown(
id='age-dropdown',
options=[{"label": a.capitalize(), "value": a} for a in FACE_AGES],
value=FACE_AGES[0],
clearable=False,
style={"width": "200px", "margin": "0 auto"}
)
])
else:
return html.Div([
dcc.Dropdown(id='sex-dropdown', value='female', style={'display': 'none'}),
dcc.Dropdown(id='age-dropdown', value='baby', style={'display': 'none'})
])
# Update carousel
@app.callback(
Output('carousel-container', 'children'),
Input('part-dropdown', 'value'),
Input('sex-dropdown', 'value'),
Input('age-dropdown', 'value'),
prevent_initial_call=False
)
def update_carousel(part, sex, age):
if part == "face":
images = face_images.get((sex, age), [])
else:
images = basic_images.get(part, [])
if not images:
return html.P("No images available.", style={"textAlign": "center"})
filename = os.path.basename(images[0])
return html.Div([
html.Div([
html.Button("⬅️", id="prev-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginRight": "15px"}),
html.Img(id="carousel-image", src=images[0],
style={"height": "409px", "display": "inline-block", "verticalAlign": "middle"}),
html.Button("➡️", id="next-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginLeft": "15px"})
], style={"display": "flex", "justifyContent": "center", "alignItems": "center", "marginBottom": "20px"}),
dcc.Store(id='image-index', data=0),
dcc.Store(id='current-images', data=images),
html.Div(f"1/{len(images)} - {filename}", id='filename-display',
style={"textAlign": "center", "fontSize": "14px", "fontStyle": "italic", "fontFamily": "Georgia, serif"})
])
# Navigation between images
@app.callback(
Output("carousel-image", "src"),
Output("image-index", "data"),
Output("filename-display", "children"),
Input("prev-button", "n_clicks"),
Input("next-button", "n_clicks"),
State("current-images", "data"),
State("image-index", "data"),
prevent_initial_call=True
)
def navigate_images(prev_clicks, next_clicks, images, index):
if not images:
return "", 0, "No images"
triggered = ctx.triggered_id
if triggered == "next-button":
index = (index + 1) % len(images)
elif triggered == "prev-button":
index = (index - 1) % len(images)
filename = os.path.basename(images[index])
return images[index], index, f"{index + 1}/{len(images)} - {filename}"
# Launch the app
if __name__ == "__main__":
clear_output(wait=True)
app.run(port=8369)
Loading...
1.2Bird Carousel¶
Source
from dash import Dash, dcc, html, Input, Output, State, ctx
from jupyter_dash import JupyterDash
import os
from IPython.display import clear_output
# Base raw GitHub URL for bird images
RAW_GITHUB = "https://raw.githubusercontent.com/SaraBarbu/Images10k-compendium/main/assets_github/birds"
# Local bird directory (just to list species)
LOCAL_BIRD_DIR = os.path.abspath("../assets_github/birds")
BIRD_SPECIES = sorted([
species for species in os.listdir(LOCAL_BIRD_DIR)
if os.path.isdir(os.path.join(LOCAL_BIRD_DIR, species))
])
# Create dictionary: {species: [image URLs]}
bird_images = {}
for species in BIRD_SPECIES:
local_folder = os.path.join(LOCAL_BIRD_DIR, species)
images = [
f"{RAW_GITHUB}/{species}/{img}"
for img in os.listdir(local_folder)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
]
bird_images[species] = sorted(images)
# Dash app setup
app = JupyterDash(__name__)
app.title = "🕊️ Bird Carousel"
app.layout = html.Div([
html.H2("🕊️ Bird Carousel", style={
"textAlign": "center", "marginBottom": "10px", "marginTop": "5px",
"fontSize": "18px", "fontWeight": "bold", "fontFamily": "Georgia, serif"
}),
html.Div([
html.Label("Select bird species:", style={"fontSize": "16px", "marginBottom": "6px", "fontFamily": "Georgia, serif"}),
dcc.Dropdown(
id='species-dropdown',
options=[{"label": s.capitalize(), "value": s} for s in BIRD_SPECIES],
value=BIRD_SPECIES[0],
clearable=False,
style={"width": "300px", "margin": "0 auto", "fontFamily": "Georgia, serif"}
)
], style={"textAlign": "center", "marginBottom": "30px"}),
html.Div(id='carousel-container', style={"textAlign": "center"})
], style={"fontFamily": "Georgia, serif", "padding": "30px"})
# Update carousel
@app.callback(
Output('carousel-container', 'children'),
Input('species-dropdown', 'value')
)
def update_carousel(species):
images = bird_images.get(species, [])
if not images:
return html.P("No images available.", style={"textAlign": "center"})
filename = os.path.basename(images[0])
return html.Div([
html.Div([
html.Button("⬅️", id="prev-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginRight": "15px"}),
html.Img(id="carousel-image", src=images[0],
style={"height": "410px", "display": "inline-block", "verticalAlign": "middle"}),
html.Button("➡️", id="next-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginLeft": "15px"}),
], style={"display": "flex", "justifyContent": "center", "alignItems": "center", "marginBottom": "20px"}),
dcc.Store(id='image-index', data=0),
dcc.Store(id='current-images', data=images),
html.Div(f"1/{len(images)} - {filename}", id='filename-display',
style={"textAlign": "center", "fontSize": "13px", "fontFamily": "Georgia, serif", "color": "#444"})
])
# Image navigation
@app.callback(
Output("carousel-image", "src"),
Output("image-index", "data"),
Output("filename-display", "children"),
Input("prev-button", "n_clicks"),
Input("next-button", "n_clicks"),
State("current-images", "data"),
State("image-index", "data"),
prevent_initial_call=True
)
def navigate_images(prev_clicks, next_clicks, images, index):
if not images:
return "", 0, "No images"
triggered = ctx.triggered_id
if triggered == "next-button":
index = (index + 1) % len(images)
elif triggered == "prev-button":
index = (index - 1) % len(images)
filename = os.path.basename(images[index])
return images[index], index, f"{index + 1}/{len(images)} - {filename}"
# Run the app
if __name__ == "__main__":
clear_output(wait=True)
app.run(port=8131)
Loading...
1.3Fish Carousel¶
Source
from dash import Dash, dcc, html, Input, Output, State, ctx
from jupyter_dash import JupyterDash
import os
from IPython.display import clear_output
# Public GitHub raw URL for fish images
RAW_GITHUB = "https://raw.githubusercontent.com/SaraBarbu/Images10k-compendium/main/assets_github/fish"
# Local path (used only to get species names)
LOCAL_FISH_DIR = os.path.abspath("../assets_github/fish")
FISH_SPECIES = sorted([
species for species in os.listdir(LOCAL_FISH_DIR)
if os.path.isdir(os.path.join(LOCAL_FISH_DIR, species))
])
# Build dictionary {species: list of image URLs}
fish_images = {}
for species in FISH_SPECIES:
local_folder = os.path.join(LOCAL_FISH_DIR, species)
images = [
f"{RAW_GITHUB}/{species}/{img}"
for img in os.listdir(local_folder)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
]
fish_images[species] = sorted(images)
# Dash app layout
app = JupyterDash(__name__)
app.title = "🐟 Fish Carousel"
app.layout = html.Div([
html.H2("🐟 Fish Carousel", style={
"textAlign": "center", "marginBottom": "10px", "marginTop": "5px",
"fontSize": "18px", "fontWeight": "bold", "fontFamily": "Georgia, serif"
}),
html.Div([
html.Label("Select fish species:", style={
"fontSize": "16px", "marginBottom": "6px", "fontFamily": "Georgia, serif"
}),
dcc.Dropdown(
id='species-dropdown',
options=[{"label": s.capitalize(), "value": s} for s in FISH_SPECIES],
value=FISH_SPECIES[0],
clearable=False,
style={"width": "300px", "margin": "0 auto", "fontFamily": "Georgia, serif"}
)
], style={"textAlign": "center", "marginBottom": "30px"}),
html.Div(id='carousel-container', style={"textAlign": "center"})
], style={"fontFamily": "Georgia, serif", "padding": "30px"})
# Update carousel
@app.callback(
Output('carousel-container', 'children'),
Input('species-dropdown', 'value')
)
def update_carousel(species):
images = fish_images.get(species, [])
if not images:
return html.P("No images available.", style={"textAlign": "center"})
filename = os.path.basename(images[0])
return html.Div([
html.Div([
html.Button("⬅️", id="prev-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginRight": "15px"}),
html.Img(id="carousel-image", src=images[0],
style={"height": "410px", "display": "inline-block", "verticalAlign": "middle"}),
html.Button("➡️", id="next-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginLeft": "15px"}),
], style={"display": "flex", "justifyContent": "center", "alignItems": "center", "marginBottom": "20px"}),
dcc.Store(id='image-index', data=0),
dcc.Store(id='current-images', data=images),
html.Div(f"1/{len(images)} - {filename}", id='filename-display',
style={"textAlign": "center", "fontSize": "13px", "fontFamily": "Georgia, serif", "color": "#444"})
])
# Navigation logic
@app.callback(
Output("carousel-image", "src"),
Output("image-index", "data"),
Output("filename-display", "children"),
Input("prev-button", "n_clicks"),
Input("next-button", "n_clicks"),
State("current-images", "data"),
State("image-index", "data"),
prevent_initial_call=True
)
def navigate_images(prev_clicks, next_clicks, images, index):
if not images:
return "", 0, "No images"
triggered = ctx.triggered_id
if triggered == "next-button":
index = (index + 1) % len(images)
elif triggered == "prev-button":
index = (index - 1) % len(images)
filename = os.path.basename(images[index])
return images[index], index, f"{index + 1}/{len(images)} - {filename}"
# Run the app
if __name__ == "__main__":
clear_output(wait=True)
app.run(port=6805)
Loading...
1.4Reptile Carousel¶
Source
from dash import dcc, html, Input, Output, State, ctx
from jupyter_dash import JupyterDash
import os
from IPython.display import clear_output
# Raw GitHub base URL for reptile images
RAW_GITHUB = "https://raw.githubusercontent.com/SaraBarbu/Images10k-compendium/main/assets_github/reptiles"
# Local directory just to get species names
LOCAL_REPTILE_DIR = os.path.abspath("../assets_github/reptiles")
REPTILE_SPECIES = sorted([
d for d in os.listdir(LOCAL_REPTILE_DIR)
if os.path.isdir(os.path.join(LOCAL_REPTILE_DIR, d))
])
# Build dictionary {species: [raw image URLs]}
reptile_images = {}
for species in REPTILE_SPECIES:
local_folder = os.path.join(LOCAL_REPTILE_DIR, species)
images = [
f"{RAW_GITHUB}/{species}/{img}"
for img in os.listdir(local_folder)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
]
reptile_images[species] = sorted(images)
# Layout
app = JupyterDash(__name__)
app.title = "🦎 Reptile Carousel"
app.layout = html.Div([
html.H2("🦎 Reptile Carousel", style={
"textAlign": "center", "marginBottom": "30px", "fontFamily": "Georgia, serif"
}),
html.Div([
dcc.Dropdown(
id='species-dropdown',
options=[{"label": s.replace("_", " ").capitalize(), "value": s} for s in REPTILE_SPECIES],
value=REPTILE_SPECIES[0],
clearable=False,
style={"width": "300px", "margin": "0 auto", "fontFamily": "Georgia, serif"}
)
], style={"textAlign": "center", "marginBottom": "20px"}),
html.Div(id='carousel-container', style={"textAlign": "center"})
])
# 🔁 Display carousel content
@app.callback(
Output('carousel-container', 'children'),
Input('species-dropdown', 'value')
)
def update_carousel(species):
images = reptile_images.get(species, [])
if not images:
return html.P("No images available.", style={"textAlign": "center"})
filename = os.path.basename(images[0])
return html.Div([
html.Div([
html.Button("⬅️", id="prev-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginRight": "15px"}),
html.Img(id="carousel-image", src=images[0],
style={"height": "410px", "display": "inline-block", "verticalAlign": "middle"}),
html.Button("➡️", id="next-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginLeft": "15px"}),
], style={"display": "flex", "justifyContent": "center", "alignItems": "center", "marginBottom": "20px"}),
dcc.Store(id='image-index', data=0),
dcc.Store(id='current-images', data=images),
html.Div(f"1/{len(images)} - {filename}", id='filename-display',
style={"textAlign": "center", "fontSize": "13px", "fontStyle": "italic", "fontFamily": "Georgia, serif"})
])
# 🔁 Navigation logic
@app.callback(
Output("carousel-image", "src"),
Output("image-index", "data"),
Output("filename-display", "children"),
Input("prev-button", "n_clicks"),
Input("next-button", "n_clicks"),
State("current-images", "data"),
State("image-index", "data"),
prevent_initial_call=True
)
def navigate_images(prev_clicks, next_clicks, images, index):
if not images:
return "", 0, "No images"
triggered = ctx.triggered_id
if triggered == "next-button":
index = (index + 1) % len(images)
elif triggered == "prev-button":
index = (index - 1) % len(images)
filename = os.path.basename(images[index])
return images[index], index, f"{index + 1}/{len(images)} - {filename}"
# Run the app
clear_output(wait=True)
app.run(port=8171)
Loading...
1.5Mammal Carousel¶
Source
from dash import dcc, html, Input, Output, State, ctx
from jupyter_dash import JupyterDash
import os
from IPython.display import clear_output
# ✅ Raw GitHub base URL for mammals
RAW_GITHUB = "https://raw.githubusercontent.com/SaraBarbu/Images10k-compendium/main/assets_github/mammals"
# ✅ Local path to read species names
LOCAL_PATH = os.path.abspath("../assets_github/mammals")
AQUATIC_FOLDER = "aquatic_mammal"
# ✅ Prepare lists
mammal_images = {}
# ✅ Load aquatic mammals
aquatic_dir = os.path.join(LOCAL_PATH, AQUATIC_FOLDER)
if os.path.exists(aquatic_dir):
for species in sorted(os.listdir(aquatic_dir)):
full_path = os.path.join(aquatic_dir, species)
if os.path.isdir(full_path):
images = [
f"{RAW_GITHUB}/{AQUATIC_FOLDER}/{species}/{img}"
for img in os.listdir(full_path)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
]
if images:
mammal_images[f"aquatic::{species}"] = sorted(images)
# ✅ Load non-aquatic mammals
for species in sorted(os.listdir(LOCAL_PATH)):
if species == AQUATIC_FOLDER:
continue
full_path = os.path.join(LOCAL_PATH, species)
if os.path.isdir(full_path):
images = [
f"{RAW_GITHUB}/{species}/{img}"
for img in os.listdir(full_path)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
]
if images:
mammal_images[f"non_aquatic::{species}"] = sorted(images)
# ✅ Dropdown options
dropdown_options = [
{"label": k.split("::")[1].replace("_", " ").title(), "value": k}
for k in mammal_images.keys()
]
# ✅ Default species
default_species_key = list(mammal_images.keys())[0] if mammal_images else None
# ✅ Build app layout
app = JupyterDash(__name__)
app.title = "🦣 Mammal Carousel"
app.layout = html.Div([
html.H2("🦣 Mammal Carousel", style={
"textAlign": "center", "marginBottom": "25px", "marginTop": "10px",
"fontFamily": "Georgia, serif"
}),
html.Div([
html.Label("Select species:"),
dcc.Dropdown(
id='species-dropdown',
options=dropdown_options,
value=default_species_key,
clearable=False,
style={"width": "300px", "margin": "0 auto"}
)
], style={"textAlign": "center", "marginBottom": "40px"}),
html.Div(id='carousel-container', style={"textAlign": "center"})
])
# 🔁 Carousel rendering
@app.callback(
Output('carousel-container', 'children'),
Input('species-dropdown', 'value'),
prevent_initial_call=False
)
def update_carousel(species_key):
if not species_key or species_key not in mammal_images:
return html.P("Please select a species.")
images = mammal_images[species_key]
filename = os.path.basename(images[0])
return html.Div([
html.Div([
html.Button("⬅️", id="prev-button", n_clicks=0, style={
"fontSize": "16px", "padding": "6px 12px", "marginRight": "10px"
}),
html.Img(id="carousel-image", src=images[0],
style={"maxHeight": "410px", "maxWidth": "400px", "margin": "0 10px"}),
html.Button("➡️", id="next-button", n_clicks=0, style={
"fontSize": "16px", "padding": "6px 12px", "marginLeft": "10px"
}),
], style={"display": "flex", "justifyContent": "center", "alignItems": "center", "marginBottom": "20px"}),
dcc.Store(id='image-index', data=0),
dcc.Store(id='current-images', data=images),
html.Div(f"1/{len(images)} - {filename}", id='filename-display',
style={"textAlign": "center", "fontSize": "14px", "fontStyle": "italic"})
])
# 🔁 Navigation buttons
@app.callback(
Output("carousel-image", "src"),
Output("image-index", "data"),
Output("filename-display", "children"),
Input("prev-button", "n_clicks"),
Input("next-button", "n_clicks"),
State("current-images", "data"),
State("image-index", "data"),
prevent_initial_call=True
)
def navigate_images(prev_clicks, next_clicks, images, index):
if not images:
return "", 0, "No images available"
triggered = ctx.triggered_id
if triggered == "next-button":
index = (index + 1) % len(images)
elif triggered == "prev-button":
index = (index - 1) % len(images)
filename = os.path.basename(images[index])
return images[index], index, f"{index + 1}/{len(images)} - {filename}"
# 🚀 Run the app
clear_output(wait=True)
app.run(port=4888)
Loading...
1.6Insect Carousel¶
Source
from dash import Dash, dcc, html, Input, Output, State, ctx
from jupyter_dash import JupyterDash
import os
from IPython.display import clear_output
# ✅ Raw GitHub base URL for insect images
RAW_GITHUB = "https://raw.githubusercontent.com/SaraBarbu/Images10k-compendium/main/assets_github/insects"
# ✅ Local insect folder to list species
LOCAL_INSECT_DIR = os.path.abspath("../assets_github/insects")
INSECT_SPECIES = sorted([
d for d in os.listdir(LOCAL_INSECT_DIR)
if os.path.isdir(os.path.join(LOCAL_INSECT_DIR, d))
])
# ✅ Create {species: [raw GitHub URLs]}
insect_images = {}
for species in INSECT_SPECIES:
folder = os.path.join(LOCAL_INSECT_DIR, species)
images = [
f"{RAW_GITHUB}/{species}/{img}"
for img in os.listdir(folder)
if img.lower().endswith((".jpg", ".jpeg", ".png"))
]
insect_images[species] = sorted(images)
# ✅ Dash app setup
app = JupyterDash(__name__)
app.title = "🐞 Insect Carousel"
app.layout = html.Div([
html.H2("🐞 Insect Carousel", style={
"textAlign": "center", "marginBottom": "20px", "marginTop": "10px",
"fontFamily": "Georgia, serif"
}),
html.Div([
html.Label("Select insect species:", style={
"fontSize": "15px", "marginBottom": "6px", "fontFamily": "Georgia, serif"
}),
dcc.Dropdown(
id='species-dropdown',
options=[{"label": s.capitalize(), "value": s} for s in INSECT_SPECIES],
value=INSECT_SPECIES[0],
clearable=False,
style={"width": "300px", "margin": "0 auto"}
)
], style={"textAlign": "center", "marginBottom": "25px"}),
html.Div(id='carousel-container', style={"textAlign": "center"})
])
# 🔁 Load carousel
@app.callback(
Output('carousel-container', 'children'),
Input('species-dropdown', 'value')
)
def update_carousel(species):
images = insect_images.get(species, [])
if not images:
return html.P("No images available.", style={"textAlign": "center"})
filename = os.path.basename(images[0])
return html.Div([
html.Div([
html.Button("⬅️", id="prev-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginRight": "15px"}),
html.Img(id="carousel-image", src=images[0],
style={"height": "410px", "display": "inline-block", "verticalAlign": "middle"}),
html.Button("➡️", id="next-button", n_clicks=0,
style={"fontSize": "16px", "padding": "5px 10px", "marginLeft": "15px"}),
], style={"display": "flex", "justifyContent": "center", "alignItems": "center", "marginBottom": "20px"}),
dcc.Store(id='image-index', data=0),
dcc.Store(id='current-images', data=images),
html.Div(f"1/{len(images)} - {filename}", id='filename-display',
style={"textAlign": "center", "fontSize": "13px", "fontStyle": "italic", "fontFamily": "Georgia, serif"})
])
# 🔁 Navigation
@app.callback(
Output("carousel-image", "src"),
Output("image-index", "data"),
Output("filename-display", "children"),
Input("prev-button", "n_clicks"),
Input("next-button", "n_clicks"),
State("current-images", "data"),
State("image-index", "data"),
prevent_initial_call=True
)
def navigate_images(prev_clicks, next_clicks, images, index):
if not images:
return "", 0, "No images"
triggered = ctx.triggered_id
if triggered == "next-button":
index = (index + 1) % len(images)
elif triggered == "prev-button":
index = (index - 1) % len(images)
filename = os.path.basename(images[index])
return images[index], index, f"{index + 1}/{len(images)} - {filename}"
# 🚀 Run the app
clear_output(wait=True)
app.run(port=8460)
Loading...