Яндекс.Метрика

    Ни о чём

    Создание серии картинок с изображениями их порядковых номеров

    В подведомственном мне компьютерном клубе, в качестве оболочки (альтернативного рабочего стола) используется RunPad Shell. Недавно вышла его новая версия в которой наконец-то появилась давно запрошенная фича: обработка переменных окружения в пути к файлу заставки.

    Я давно хотел поставить на каждом компьютере заставку с его номером, но не хотел настраивать каждый комп по отдельности. А сейчас можно одним ударом прописать всем путь «J:\_rs\scrsvr\%rs_machine%.jpg» и дело за малым — нарисовать картинки.

    Но каким образом можно получить набор картинок с изображениями их порядковых номеров?
    Рисовать вручную — тупо и не спортивно. Придётся всю жизнь мириться с тем, что сходу получится, потому что второй раз рука уже не поднимется.

    Написать программу — грубо и прямолинейно. Особенно учитывая, что почти все программы уже написаны до нас, и нужно только найти подходящую.

    Решение хотелось получить максимально простым и гибким. Но обязательно с привлечением каких-нибудь ранее неизученных средств и технологий, чтоб было интересно и полезно.

    Из подручных средств имелся только домашний линукс, поэтому план действий был выбран следующий:
    1. Берём малознакомый Image Magic и выясняем какие ключи ему нужно передать на вход, чтоб на выходе получить картинку определённого разрешения с надписью максимально большими шрифтом (чтоб издалека было видно).
    2. Берём Bash и изучаем неведомый ранее shell scripting до тех пор, пока не станет ясно, как организовать его средствами цикличный запуск команды со счётчиком цикла среди параметров.
    3. Пробуем соединить 1 и 2 и написав скрипт, который с помощью imagic создаст набор картинок с заданными параметрами.

    Image Magic


    В мануале есть специальный раздел «ImageMagick Text to Image Handling» в котором описываются все параметры касающиеся нанесения текста на изображения. Не буду описывать всё, что мне пригодилось, а заострю внимание лишь на одной интересной особенности.

    Моё внимание сразу привлёк подраздел Best Fit to Image. В нём говорится, что при использовании параметра -size (размер холста) вместо -pointsize (размер шрифта), imagic сам выберет максимальный размер шрифта для полного заполнения картинки текстом. На первый взгляд это как раз то, что нужно.

    Пробуем:
    convert -size 1024x768 -background black -fill white -gravity center label:42 image.jpg
    42

    Результат удручающий. Во первых — картинка генерируется почти 20 секунд. Видимо IM генерирует несколько изображений последовательно увеличивая кегль, пока надпись ещё вписывается в указанные размеры.

    Во вторых — на мониторе надпись будет располагаться не по центру. Если же обрезать всё лишнее, заменив параметр -gravity center на -trim +repage, то получится картинка меньших размеров, чем указано в задании.

    convert -size 1024x768 -background black -fill white -trim +repage label:42 image.jpg
    trimmed 42

    Придётся подобрать размеры вручную. При этом может понадобиться возможность указать координаты, начиная с которых imagic должен будет вставлять текст, так как отступ снизу, на первом варианте, появился не спроста.

    Кроме Label существует ещё несколько способов рисования: Caption, Draw и Annotate. Однако Caption не позволяет указать координаты, в которых нужно наносить надпись, а Draw, исходя из документации, кривой и устаревший.

    Нанесение надписи с помощью Annotate возможно только на существующее изображение, поэтому потребовалось дополнительно указать параметр xc, чтобы холст автоматически создавался. Так как в этом же параметре можно указать и цвет холста, то параметр -background больше можно не использовать.

    convert -size 1024x768 xc:black -pointsize 900 -fill white -gravity center -annotate +0+0 "42" image.jpg
    42 xc

    Получилось почти тоже самое, что и в первом случае, но теперь на генерацию картинки уходит меньше секунды и появилась возможность указывать относительное смещение надписи. Используем её подвинув текст ниже.

    convert -size 1024x768 xc:black -pointsize 900 -fill white -gravity center -annotate +0+70 "42" image.jpg
    42 final

    Ну вот, это как раз то, что нужно. На этом с Image Magic пока можно закончить.


    Bash scripting


    Прежде я особо и не читал никаких скриптов на Bash, не говоря уже о том, чтоб писать на нём что-нибудь. Общее представление о языке конечно было, но опыт отсутствовал напрочь.

    Стартануть помогло замечательное руководство Advanced Bash Scripting (eng, рус), которое, насколько мне известно, издаётся и в бумажном виде. Терпения хватило только на первые пару глав и разобравшись с переменными я сразу перешёл к циклам.

    Оказалось, что прогнать цикл можно несколькими способами. Своей лаконичностью и ясностью мне больше понравился такой:

    #!/bin/bash
    for i in $(seq 1 10)
    do
        echo "Hello $i times"
    done


    Во многих скриптовых языках можно попросить интерпретатор выполнить системную команду заключив её в `обратные апострофы`, а экранируя перевод строки обратным слешем \, можно ввести многострочную команду даже в консоль.

    Теперь можно попробовать собрать всё вместе.

    #!/bin/bash
    for i in $(seq 1 50)
    do
        `convert \
            -size 1024x768 \
            xc:black \
            -pointsize 900 \
            -fill white \
            -gravity center \
            -annotate +0+70 "$i" \
            ${i}.jpg`
    done

    Получилось!

    script result

    После этого я ещё немного поигрался с параметрами imagic и благодаря удачному примеру добился свечения у цифр, соответствующего названию клуба — «Неон» :-)

    neon


    Результат в натуре


    42 :-)

    23-25

    4-8