0

Есть маленький спрайт:

# спрайт Марио в base64 записать в файл:
magick 'inline:data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAA7EAAAO
xAGVKw4bAAAA00lEQVQ4ja1UwRGDMAyTe7zLJmWUzMoodBO6gHmkhsRWcukVvYID
kiKbiKoqbsTjTjIAmLq7IvXzwGHahJ5sUKBJKKhf3rcVAPB8pZ5BTihyEcxLomuD
Fxhqyryk06WtDZ93LSB+bMqYvBtPBsQYA2FP3YPl2XUIAIpcsCZ5eRM18slvALyL
CoFAu5EApCn7tsbx+hY0U55llmkYG7NefuhzKAVFUv1Mm8L+EgKWa5zDQbIWqiNn
riuvID8g1r4c2Hi6Ghvg6sg/mqEIDv+9v2+/sQ8vtmAvY/Wf0QAAAABJRU5ErkJg
gg==' mario.png

Я хочу отмасштабировать его в 8 раз:

convert -scale 800%  -quality 100 mario.xpm mario-big.png

Но отмасштабировать нужно с отступами между пикселями. Чтобы между четырьмя соседними увеличенными в 8х раз пикселями был отступ в 1 пиксель. Либо наложить поверх сетку цвета фона с учётом размеров исхоного спрайта.

Как можно это сделать, подскажите пожалуйста?

Пример того, что я хочу увидеть:введите сюда описание изображения

2 Answers2

3

Эту задачу можно решить с помощью следующей команды:

convert mario.png \
  -scale 800% \
  -crop 0x8 -splice 0x1 -append \
  -crop 8x0 -splice 1x0 +append \
  -chop 1x1 output.png

Если исходное изображение было 20x20 пикселей, то на выходе получим изображение размером 179x179:

output.png

Разберем по шагам:

  • -scale — масштабирование изображения, увеличиваем изображение в 8 раз с помощью команды -scale 800%.
  • -crop — эта команда нарезает изображение на куски указанного размера. Если передаем 0 в качестве ширины, то берется максимальная ширина. То есть -crop 0x8 нарежет изображение на горизонтальные полоски размера 160x8.
  • -splice — добавление строк или колонок в указанное место. Команда -splice 0x1 добавит полоску размера 160x1 в начало изображения. Эта команда применяется к каждому куску из предыдущего шага.
  • -append — этой командой соединяем модифицированные изображения с предыдущего шага в одно изображение. Изображения соединяются друг за другом по вертикали.
  • Далее аналогично применяются -crop и -splice, но изображение нарезается по вертикальным полоскам.
  • +append — соединяет изображения в горизонтальном направлении.
  • -chop — операция, противоположная splice, удаляет указанные строки и столбцы. Команда -chop 1x1 удалит столбец и строку по 1 пикселю в начале изображения.
  • Спасибо! Очень круто. Лучше другого варианта, где пришлось резать кучу файлов и добавлять цикл.. А можете объяснить, что происходит в вашем скрипте? Хочется понимать. – PedroSangre Sep 04 '22 at 16:13
  • Подробнее изучил процесс, большое спасибо за разложение по полочкам и разметку markdown. С чужих объяснений понять, пусть и не сразу, могу, но сам сгенерировать, сколько не читал инструкций по IM - не могу. Неужели я тупой?)
    Зачем в данном случае -chop 1x1 попробовал без него - получается тоже самое, только без смещения. Запутался, как лучше.
    – PedroSangre Sep 06 '22 at 12:29
1

Мне ещё так советовали с циклом:

magick mario-big.png -crop x8 mario-row-%02d.png ; for f in mario-row-*png ; \
do echo $f; magick "$f" -crop 8x -background "#fffffe" +smush 1 "$f"; done ; \
magick mario-row-*png -background "#fffffe" -smush 1 mario-big3.png ; rm mario-row-*.png

Это же подробнее bash-скриптом:

#!/bin/bash

Chop into rows, each row being 50px tall

magick artistic-swirl.jpg -crop x50 row-%02d.png

Iterate over rows, chopping each into 50px wide chunks and recombining with 1px spacing

for f in row-*png ; do echo $f magick "$f" -crop 50x -background yellow +smush 1 "$f" done

Smush the new rows together vertically with 1px spacing

magick row-*png -background cyan -smush 1 result.png

Почти то, что надо, только временные файлы создаёт и их потом удалять надо. И нельзя указать для рамки оба цвета как white - продают все цвета вообще. Обхожу это указывая на байт меньше: #fffffe Глазу разницы не видно, но почему так, кто скажет?

Подробности тут: https://stackoverflow.com/questions/73590651/i-want-to-scale-the-sprite-8x-with-padding-between-pixels

  • Старайтесь давать чуть более развернутые ответы и пояснять что происходит в приложенном вами коде, чтобы пользователи, которые столкнулись с той же проблемой смогли понять, что вы делаете, почему и как вы к этому пришли... в противном случае пользы от него для окружающих не так много – Михаил Ребров Sep 04 '22 at 16:07
  • 1
    ОК. просто не успел добавить описание. – PedroSangre Sep 04 '22 at 16:11
  • плюсик вам в карму – Михаил Ребров Sep 04 '22 at 16:44
  • Обхожу это указывая на байт меньше: #fffffe Глазу разницы не видно, но почему так, кто скажет? вопросы в ответе писать - тоже не лучшая идея :) – Михаил Ребров Sep 04 '22 at 16:45
  • Следует ли из-за такой мелочи создавать новый вопрос? – PedroSangre Sep 06 '22 at 12:47
  • если хотите получить ответ - то да. Искать вопросы в ответах тут точно никто не будет. И отвечать ответом на ответ тоже. И даже если вы это перенесете в тело текущего вопроса - скорее всего этого никто не заметит, потому что вопрос уже решен и имеет два ответа. То, что ответ изменился после получения этих ответов и что он требует каких-то новых ответов никто предполагать не будет. Более того правилами сервиса установлено, что посты в которых содержится более одного вопроса стоит разделять. Так что все зависит от того насколько вы хотите получить ответ. – Михаил Ребров Sep 06 '22 at 12:55
  • Это просто совет, а не руководство к действию. Я просто объясняю как сервис работает и предупреждаю что на вопрос заданный в ответе вы ответа не дождетесь - далее уже решать вам. – Михаил Ребров Sep 06 '22 at 12:57