Объединение картинок ( сводный лист, предпросмотр фильма ) [SOLVED]

Здравствуйте.
Столкнулся с проблемкой :
Требуется создать "предпросмотр" к фильму - набор скриншотов, обьединённых на одной картинке.
Сами скриншоты с горем пополам сделал - помогла программа VLC Client - наиболее удобно делать - нажимаешь кнопочку и она создаёт скрин без лишних вопросов.
Любимый Каффеин постоянно выводит диалог сохранения, в МПлеере вообше не нашёл упоминания про скрины (хотя консольную версию не смотрел).
Далее - объединение их всех в один файл автоматом - тишина.
В Гимпе нашёл только функцию объединения в "фотоплёнку".

Нашёл в программе FastStone под Wine - там это называется Сводный лист.
Выделяешь нужные картинки, тыкаешь, задаёшь кол-во столбцов и строк в выходном листе и получаешь картинку...

Может кто подсказать метод решения данной проблемы только под Линуксом?
Кто чем делает скрины?
Не обязательно программу с ГУИ, можно и в командной строке задавать имена файлов - просто неохота ручками всё это перемещать и править.

Решил добавить листинг скрипта сюда.

Изменения скрипта:

2007.06.19 Теперь скрипт корректно обрабатывает имена с пробелами, скобками , например:
make-thumbs.sh Успеть\ до\ полуночи\[\]\{\}\"\".avi
make-thumbs.sh "Успеть до полуночи[]{}\"\".avi"

2007.06.21 Промежуточные файлы создаются в директории /tmp
Выходной файл в формате jpg , качество 100
Если отсутствуют аргументы - выводится подсказка по скрипту и скрипт завершается
Изменение при сборе информации о файле (1 вызов mplayer вместо 3х)
Изменения в циклах набора кадров и удаления кадров-файлов

Собственно сам скрипт (последняя версия):

FILE="$1"; # Имя файла

Image_Rows="$2"; # Кол-во строк
Image_Columns="$3"; # Кол-во столбцов
Image_Resolution="$4"; # Разрешение выходного изображения

# Для "отлова" кадров
Time_Shift="$5"; # Временное смещение
File_Suffix="$6"; # Суффикс файла ,например, aaa.avi -> aaa_1.jpg aaa_2.jpg

#+++ В случае, если значения не заданы
if [ "$FILE" = "" ]
then
echo 'Не указан видео-файл !';
echo 'Использование <видео-файл> [кол-во строк] [кол-во столбцов] [разрешение выходнго изображения] [временное смещение] [суффикс выходного файла]';
echo 'Суффикс файла обычно число. Получающийся выходной файл <видео-файл>_<число-суффикс>.jpg';
echo 'Качество выходного jpg-файла - 100';
exit 1;
fi

if [ "$Image_Rows" = "" ]
then
Image_Rows="3"
fi

if [ "$Image_Columns" = "" ]
then
Image_Columns="3"
fi

if [ "$Image_Resolution" = "" ]
then
Image_Resolution="1024x768"
fi
if [ "$Image_Resolution" = "0" ]
then
Image_Resolution="1024x768"
fi

if [ "$Time_Shift" = "" ]
then
Time_Shift="0"
fi

if [ "$File_Suffix" != "" ]
then
File_Suffix="_$File_Suffix";
fi
#--- В случае, если значения не заданы

FILENAME=${FILE%.*};

# Промежуточная переменная INFO хранит данные о видео-файле
INFO=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"`;

# Высота исходного видео-кадра
HEIGHT=`expr "$INFO" : '.*HEIGHT=\([0-9]*\)'`;

# Ширина исходного видео-кадра
WIDTH=`expr "$INFO" : '.*WIDTH=\([0-9]*\)'`;

# Кол-во кадров - используется для набор кадров и удаления файлов-кадров
NUM=$(($Image_Rows*$Image_Columns));

# Временной "шаг" - шаг по времени для набора снимков
LEN=$((`expr "$INFO" : '.*LENGTH=\([0-9]*\)'`/( $NUM +2)));

#+++ Набираем кадры
for kadr in `seq 1 $NUM`
do
echo "Обработка кадра $kadr из $NUM";
mplayer -msglevel all=0 -nosound -vo jpeg:outdir=/tmp:quality=100 -frames 2 -ss `echo $Time_Shift+$kadr*$LEN|bc` "$1" > /dev/null;
rm /tmp/00000001.jpg;
mv /tmp/00000002.jpg /tmp/"$kadr.jpg";
done
#--- Набираем кадры

#+++ Вставляем кадры
echo Вставка кадров...;
Command="convert ";
for i in `seq 1 $Image_Rows`
do
for j in `seq 1 $Image_Columns`
do
kadr=`echo "($i-1)*$Image_Columns+$j"|bc`;
x_pos=$(( ($HEIGHT+10)*($i-1) ));
y_pos=$(( ($WIDTH+10)*($j-1) ));
Command="$Command -page +$y_pos+$x_pos /tmp/$kadr.jpg";

done
done
Command="$Command -background white -mosaic -bordercolor white -border 10x10 -quality 100 /tmp/tmp0.jpg";
$Command;
#--- Вставляем кадры

# Меняем размер
convert /tmp/tmp0.jpg -auto-orient -thumbnail $Image_Resolution -quality 100 /tmp/tmp.jpg

#+++ Чистка временных файлов
for kadr in `seq 1 $NUM`
do
rm /tmp/"$kadr.jpg";
done
rm /tmp/tmp0.jpg;
#--- Чистка временных файлов

mv /tmp/tmp.jpg "$FILENAME$File_Suffix.jpg"
echo Готово! - файл "$FILENAME$File_Suffix.jpg"

thumb.sh

#!/bin/bash
FILE="$1";
FILENAME=${FILE%.*};
HEIGHT=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_VIDEO_HEIGHT="|cut -d = -f2`
HEIGHT2=$(($HEIGHT+10));
HEIGHT3=$(($HEIGHT+$HEIGHT+20));
WIDTH=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_VIDEO_WIDTH="|cut -d = -f2`
WIDTH2=$(($WIDTH+10));
LEN=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_LENGTH="|cut -d = -f2`
LEN=`echo "$LEN/8"|bc`;

for i in `seq 1 6`;
do
mplayer -msglevel all=0 -nosound -vo png -frames 2 -ss `echo $LEN+$i*$LEN|bc` "$1";
rm 00000001.png;
mv 00000002.png "$i.png";
done

convert -page +0+0 1.png -page +$WIDTH2+0 2.png -page +0+$HEIGHT2 3.png -page +$WIDTH2+$HEIGHT2 4.png -page +0+$HEIGHT3 5.png -page +$WIDTH2+$HEIGHT3 6.png -background black -mosaic -bordercolor black -border 10x10 "$FILENAME.png"
convert -size $WIDTHx$HEIGHT "$FILENAME.png" -auto-orient -thumbnail 1024x768 tmp.png

for i in `seq 1 6`;
do
rm -rf $i.png
done
mv tmp.png "$FILENAME.png"

пользую вот такой скрипт.

./thumb.sh video.avi

а mplayer можно запустить mplayer -vf screenshot, а потом жмешь s и получаешь скриншот.

Спасибо

Спасибо большое :)
Проблема успешно решена.

Немного похимичил на скриптом

Содержание файла make-thumbs-wad.sh :

FILE="$1"; # Имя файла

Image_Rows="$2"; # Кол-во строк
Image_Columns="$3"; # Кол-во столбцов
Image_Resolution="$4"; # Разрешение выходного изображения

# Для "отлова" кадров
Time_Shift="$5"; # Временное смещение
File_Suffix="$6"; # Суффикс файла ,например, aaa.avi -> aaa_1.png aaa_2.png

#--- В случае, если значения не заданы
if [ "$Image_Rows" = "" ]
then
Image_Rows="3"
fi

if [ "$Image_Columns" = "" ]
then
Image_Columns="3"
fi

if [ "$Image_Resolution" = "" ]
then
Image_Resolution="1024x768"
fi
if [ "$Image_Resolution" = "0" ]
then
Image_Resolution="1024x768"
fi

if [ "$Time_Shift" = "" ]
then
Time_Shift="0"
fi

if [ "$File_Suffix" != "" ]
then
File_Suffix="_$File_Suffix";
fi

#--- В случае, если значения не заданы

FILENAME=${FILE%.*};
# Высота исходного видео-кадра
HEIGHT=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_VIDEO_HEIGHT="|cut -d = -f2`

HEIGHT2=$(($HEIGHT+10));
HEIGHT3=$(($HEIGHT+$HEIGHT+20));

# Ширина исходного видео-кадра
WIDTH=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_VIDEO_WIDTH="|cut -d = -f2`

WIDTH2=$(($WIDTH+10));

# Временной "шаг"
LEN=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_LENGTH="|cut -d = -f2`
LEN=`echo "$LEN/($Image_Rows*$Image_Columns +2 )"|bc`;

#+++ Набираем кадры
for i in `seq 1 $Image_Rows`
do
for j in `seq 1 $Image_Columns`
do
kadr=`echo "($i-1)*$Image_Columns+$j"|bc`;
echo Обработка кадра $kadr;

mplayer -msglevel all=0 -nosound -vo png -frames 2 -ss `echo $Time_Shift+$LEN+$kadr*$LEN|bc` "$1" > /dev/null;
rm 00000001.png;
mv 00000002.png "$kadr.png";
done
done
#--- Набираем кадры

#+++ Вставляем кадры
echo Вставка кадров...;
Command="convert ";
for i in `seq 1 $Image_Rows`
do
for j in `seq 1 $Image_Columns`
do
kadr=`echo "($i-1)*$Image_Columns+$j"|bc`;
x_pos=$(( ($HEIGHT+10)*($i-1) ));
y_pos=$(( ($WIDTH+10)*($j-1) ));
Command="$Command -page +$y_pos+$x_pos $kadr.png";

done
done
Command="$Command -background white -mosaic -bordercolor white -border 10x10 $FILENAME.png";
$Command;
#--- Вставляем кадры

# Меняем размер
convert -size $WIDTHx$HEIGHT "$FILENAME.png" -auto-orient -thumbnail $Image_Resolution tmp.png

#+++ Чистка временных файлов
for i in `seq 1 $Image_Rows`
do
for j in `seq 1 $Image_Columns`
do
kadr=`echo "($i-1)*$Image_Columns+$j"|bc`;
rm "$kadr.png";
done
done
#--- Чистка временных файлов

mv tmp.png "$FILENAME$File_Suffix.png"
echo Готово! - файл "$FILENAME$File_Suffix.png"

Использование

Не забываем сделать файл исполняемым...

Использование :
make-thumbs.sh <имя файла> <строки> <столбцы> <разрешение> <время> <суффикс>

Пример:
wad@wad /mnt/sda1/FILMS $ /home/wad/make-thumbs.sh Interstate_60.avi 5 4 0 0 1

Скрипт у меня лежит в домашней папке, запускаю его из директории с фильмами

Получаю - файл Interstate_60_1.png с 5ю строками, 4мя рядами, разрешением 1024на768 и с нулевым сдвигом по кадрам.

Если выходная картинка не нравится - меняю на
wad@wad /mnt/sda1/FILMS $ /home/wad/make-thumbs.sh Interstate_60.avi 5 4 0 5 2
получаю Interstate_60_2.png с немного другими кадрами :)

Можно сказать - почти мой, но первый скрипт :))

bug

Там где имена файлов киношек которые содежать символы маскируемые слэшем (типа с пробелами, или со скобками) конечный png файл создатся не может.

а вообще работает замечательно
вот превьюшка к умолчальному результату к мультику "Полигон"

вот здесь вариант 5 4 0 0 1

а здесь 5 4 0 5 2

дальше сами играйтесь
_________________
:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

взял сделанный

взял сделанный тобой и немного поправил в плане производительности.
Теперь не запускается 3 раза mplayer, чтоб узнать высоту ширину и длительность, и скриншоты делаются сразу нужного размера. Еще сделал чтоб временные файлы создавались в /tmp
сложил на ru.gentoo-wiki.com

пусть живет там %))
_________________
2B |! 2B

Re: взял сделанный

pasha написал(а):
взял сделанный тобой и немного поправил в плане производительности.
Теперь не запускается 3 раза mplayer, чтоб узнать высоту ширину и длительность, и скриншоты делаются сразу нужного размера. Еще сделал чтоб временные файлы создавались в /tmp
сложил на [url=http://ru.gentoo-wiki.com/http://ru.gentoo-wiki.com/Сводный_лист_(предпросмотр)_фильма]ru.gentoo-wiki.com[/url]
пусть живет там %))

Большое спасибо
скрипт по завершению работы выдают ошибку
rm: cannot remove `/tmp/poligon.jpg': No such file or directory
и хронография кадров сбивается

PS

если запустить скрипт без аргументов то будет ругатся
line 55: /(12+2): syntax error: operand expected (error token is "/(12+2)") вместо того что бы показать usage

_________________
:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

Немного :)

Немного поправил. Такие циклы загубил :)

Насчёт /tmp - мысль хорошая - а то список файлов - обновляется - "моргает".

Насчёт jpg - не най - я лично предпочитаю png.
Насчёт циклов и другого метода склеивания - остаюсь при своей версии :)
Насчёт "montage -background \#FFFFFF" - white он не понимает?
Насчёт "$File_Suffix$FILENAME.jpg" - File_Suffix там выставляется _1 _2 или что-то похожее. Это не приставка - используется для получения файлов вида ааа_1 ааа_2, а не 1_ааа . Просто файлы ааа_<число> будут при сортировке по имени рядом.

Вообщем, остаюсь при своей версии. Попозже подработаю насчёт промежуточных файлов в tmp.
Насчёт выкладывания на ru.gentoo-wiki.com - не против, единственно, я бы хотел сохранить "мою" вариацию - можно 2е вариации выложить :)

Изменения

Изменения 2007.06.21 :
Промежуточные файлы создаются в директории /tmp
Выходной файл в формате jpg , качество 100

:. пустой запуск

А можно добавить в скрипт обработку пустого запуска, типа подсказки как он работает
Сейчас если файл запускать без указания фильма то он выдает кучу parse errors.

_________________
:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

Добавил

Добавил.
На всякий случай напоминаю, что последнюю версию выкладываю в первом сообщении.

Предлагаю объеденить варианты.

Хотелось бы не плодить все таки два варианта.
давай на вики оставим только твой, но я бы таки заменил вот этот кусок.

HEIGHT=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_VIDEO_HEIGHT="|cut -d = -f2`
# Ширина исходного видео-кадра
WIDTH=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_VIDEO_WIDTH="|cut -d = -f2`
# Временной "шаг"
LEN=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"|grep "^ID_LENGTH="|cut -d = -f2`
LEN=`echo "$LEN/($Image_Rows*$Image_Columns +2 )"|bc`;

на

INFO=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$1"`;
HEIGHT=`expr "$INFO" : '.*HEIGHT=\([0-9]*\)'`;
WIDTH=`expr "$INFO" : '.*WIDTH=\([0-9]*\)'`;
NUM=$(($Image_Rows*$Image_Columns));
LEN=$((`expr "$INFO" : '.*LENGTH=\([0-9]*\)'`/($NUM+2)));

оно побыстрее будет.
И объясни почему цикл лучше? плз.
_________________
2B |! 2B

Кусок поменял -

Кусок поменял - как говорится - твоя правда :)

Два цикла из 3х тоже поменял. Теперь просто по номеру кадра бегают.
Где обьединение картинок оставил i и j- проще понять логику работы.
Насчёт Вики согласен.

Doctor - зарегился на Вики, счас обновлю скрипт. Картинки оставлю.

:. добавил картинок

Я туда еще картинок добавил, и чуть чуть викифицировал ;)
аж самому понравилось :D
_________________
:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

:. Добавил

Прошу [url=http://ru.gentoo-wiki.com/Сводный_лист_(предпросмотр)_фильма]взглянуть[/url], и возможно поправить если потребуется.

Всем большое спасибо.
_________________
:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

:. VideoCut

Наткнулся на VideoCut


--
:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

Запоздал

Запоздал немного.
Doctor , можно ближе к концу добавить раздел - Аналоги - и вписать ссылку на программу.

Мне пока скрипта хватает по функциональности, хотя подписи "время кадра" иногда могут быть полезны.
Но как я понял - convert позволяет писать на изображении ( -annotate )
Можно добавить такую функцию в скрипт.

Поставил - посмотрел.
Что понравилось - время кадра :)
Что не понравилось - мне удобней задавать размер выходного изображения, а не процент сжатия кадров.

gentoo-wiki всегда открыта

Добавить аналоги разумеется можно - пускай народ знает из чего выбирать,
если не против, залей свой собственный screenshot.

mplayer показывает время опцией -osdlevel [0|1|2|3]

размер выходного изображения на мой взгляд тоже удобнее

:. Поделись опытом на ru.gentoo-wiki.com или на www.gentoo-wiki.com

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".