IAVG-HTML - Приложение для удобного просмотра gif и webm сборников в браузере
Приложение Image and Video Gallery (IAVG-HTML) предназначено для автоматического создания HTML-галереи изображений и видеофайлов, находящихся в текущей директории. Оно генерирует веб-страницу, на которой вы можете удобно просматривать контент.
Предисловие
Ещё с давних времён, завалялся у меня сборник gif-ок на CD-диске, решил я в нем покопаться, однако нормально посмотреть содержимое не удалось. Встроенный в современные операционные системы просмотрщик не анимирует gif-файлы при просмотре. Открывать в браузере по одной анимации - то ещё удовольствие. Плюсом подвернулся архив коротких webm-фалов, с которыми аналогичная проблема. Так в поисках решения для удобного просмотра подобного контента было разработано следующее приложение. Выполняя приложение в папке с контентом - получаем html-файл, запускаем его в браузере и получаем просмотр аля “Shorts”. Делюсь своими наработками.
Функциональные возможности
- Автоматическое сканирование текущей директории на наличие файлов изображений и видео.
- Поддержка форматов: JPG, JPEG, PNG, GIF, WEBM.
- Создание адаптивной HTML-страницы с удобной навигацией.
- Ленивая загрузка изображений и видео для оптимизации скорости работы.
- Плавная прокрутка между элементами галереи.
- Быстрый переход к конкретному файлу по его порядковому номеру.
- Поддержка управления клавишами (ArrowUp и ArrowDown).
Принцип работы
- Приложение сканирует текущую папку на наличие поддерживаемых файлов.
- Создаёт HTML-файл с галереей, где каждый файл представлен в отдельной секции.
- Готовый HTML-файл сохраняется под именем "!outputap.html".
Как использовать
- Сохраните Python-скрипт и запустите его в каталоге с изображениями и видео.
- После выполнения скрипта откройте сгенерированный файл "!outputap.html" в браузере.
- Используйте клавиши управления или поле ввода для навигации по галерее.
Код:
import os
# Название выходного HTML-файла
output_file = "!outputap.html"
# Начало HTML-файла
html_content = """
<html>
<head>
<title>Image and Video Gallery</title>
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
font-family: Arial, sans-serif;
}
.container {
scroll-snap-type: y mandatory;
overflow-y: scroll;
height: 100vh;
padding: 5px; /* Отступ от краев браузера */
box-sizing: border-box; /* Учитываем padding в размерах */
}
.frame {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
max-width: 1600px;
height: calc(100vh - 10px); /* Учитываем отступы */
margin: 0 auto;
border: 2px solid #ccc;
box-sizing: border-box;
overflow: hidden;
padding: 5px; /* Отступ от границ блока */
}
.content {
max-width: 100%;
max-height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
.content img, .content video {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
scroll-snap-align: start;
}
h2 {
text-align: center; /* Заголовок по центру */
margin: 0; /* Убираем margin */
padding-top: 7px; /* Отступ сверху 7px (5px + 2px) */
box-sizing: border-box; /* Учитываем padding в размерах */
}
/* Плавающий блок с элементами управления */
.controls {
position: fixed;
bottom: 30px; /* Учитываем отступ от краев браузера */
right: 30px; /* Учитываем отступ от краев браузера */
background: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
gap: 10px;
}
.controls input {
padding: 5px;
font-size: 16px;
width: 100px;
}
.controls button {
padding: 5px 10px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1 style="text-align: center; padding: 20px;">Image and Video Gallery</h1>
"""
# Счетчик для порядкового номера контента
counter = 1
# Поиск .gif, .webm, .jpg, .jpeg и .png файлов в текущей папке
for file in os.listdir("."):
if file.lower().endswith((".gif", ".webm", ".jpg", ".jpeg", ".png")):
html_content += f"""
<div class="section">
<div class="frame">
<h2>{counter}. {file}</h2> <!-- Добавлен порядковый номер -->
"""
if file.lower().endswith(".gif"):
html_content += f"""
<div class="content">
<img data-src="{file}" alt="{file}">
</div>
"""
elif file.lower().endswith(".webm"):
html_content += f"""
<div class="content">
<video controls loop autoplay muted data-src="{file}">
Your browser does not support the video tag.
</video>
</div>
"""
elif file.lower().endswith((".jpg", ".jpeg", ".png")):
html_content += f"""
<div class="content">
<img data-src="{file}" alt="{file}">
</div>
"""
html_content += """
</div>
</div>
"""
counter += 1 # Увеличиваем счетчик
# Конец HTML-файла
html_content += """
</div>
<!-- Плавающий блок с элементами управления -->
<div class="controls">
<input type="number" id="sectionNumber" placeholder="Номер" min="1" />
<button onclick="goToSection()">Перейти</button>
</div>
<script>
// Функция для перехода к конкретному номеру контента
function goToSection() {
const sectionNumber = parseInt(document.getElementById('sectionNumber').value);
if (sectionNumber >= 1) {
const targetSection = document.querySelector(`.section:nth-child(${sectionNumber + 1})`);
if (targetSection) {
targetSection.scrollIntoView({ behavior: 'smooth' });
}
}
}
// Обработка клавиш для прокрутки
document.addEventListener('keydown', function(event) {
if (event.key === 'ArrowDown') {
window.scrollBy({ top: window.innerHeight, behavior: 'smooth' });
} else if (event.key === 'ArrowUp') {
window.scrollBy({ top: -window.innerHeight, behavior: 'smooth' });
}
});
// Ленивая загрузка с использованием Intersection Observer
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const content = entry.target.querySelector('.content');
if (content) {
const img = content.querySelector('img');
const video = content.querySelector('video');
if (img && img.dataset.src) {
img.src = img.dataset.src; // Загружаем изображение
}
if (video && video.dataset.src) {
video.innerHTML = `<source src="${video.dataset.src}" type="video/webm">`; // Загружаем видео
}
}
observer.unobserve(entry.target); // Прекращаем наблюдение после загрузки
}
});
}, { threshold: 0.5 }); // Порог видимости 50%
// Наблюдаем за всеми секциями
document.querySelectorAll('.section').forEach(section => {
observer.observe(section);
});
</script>
</body>
</html>
"""
# Сохранение HTML-файла
with open(output_file, "w", encoding="utf-8") as f:
f.write(html_content)
print(f"HTML-файл '{output_file}' успешно создан.")
Минимальные системные требования
Для выполнения в виде скрипта
- Операционная система: Windows 7/8/10/11, Linux, macOS
- Python 3.6 или выше
Для выполнения в виде скомпилированного приложения
- Операционная система: Windows 7/8/10/11
Заключение
Приложение IAVG-HTML — это удобный инструмент для быстрого создания HTML-галерей. Оно автоматически формирует удобную навигацию и обеспечивает плавный просмотр контента. Скомпилированная версия приложения, будет размещена в загрузках.