LINUX.ORG.RU

Изучаю возможности ImageMagick - тред #1 графические примитивы

 


0

1

Howdy!

Хочу на холсте нарисовать несколько пикселей.

magick -size 10x6 xc:khaki -fill black -draw 'point 3,2' draw_point.gif
magick -size 10x6 xc:khaki -fill black -draw 'point 3,2 point 1,2' draw_point.gif

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

Нагуглил такой метод:

input.txt

# ImageMagick pixel enumeration: 3,4,255,rgb
0,0  
1,0: (0,0,0)
2,0: (255,255,255)  
0,1: (0,0,0) 
1,1: (255,255,255)   
2,1: (0,0,0) 
0,2: (255,255,255)    
1,2: (0,0,0)        
02,03: (0,0,0)         

Теперь по этому файлу создаём наш пиксель арт:

convert -background tan txt:input.txt -filter point -resize 64x64! output.png

Прекрасно, у меня получилось! Я даже воспылал вдохновением и попробовал нарисовать спрайт Марио. Но не тут-то было. Хотя в документации пишут, что: you do NOT need to define ALL the pixels. на самом деле нельзя описать пиксели с не нулевой x позиции. Нужно построчно слева направо описать, пусть не до правой границы, но если начать новую строку не с первой колонки, то error/convert.c/ConvertImageCommand/3325.

Я попробовал с этим смириться, и описал голову Марио: https://pastebin.com/TyyDSibf

convert -background tan txt:mario.txt -filter point -resize 64x64 mario.png
convert: no images defined `mario.png' @ error/convert.c/ConvertImageCommand/3325.

Даже если бы получилось, то при смене background пришлось бы менять цвет ведущих с начала строки лишних пикселей (да, у меня для теста они 255) и они занимают кучу лишнего места, и не получилось.

ЧЯДНТ?

Помогите plz правильно описать спрайт Марио.

Можно конечно и так:

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

Но эта компиляция неудобна для редактирования точек и я хочу освоить данный инструмент txt:. Но описывать только те точки, что хочу. И желательно не кодами, а именами, которые почему-то не проходят.

Ссылки:

Перемещено hobbit из general

★★★

Последнее исправление: hikikomori (всего исправлений: 1)

Теоретически может и интересно разобраться почему там что-то не так работает, но практически то зачем? У тебя получается неудобный пиксельный редактор с запредельно громоздким форматом хранения.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Практический смысл - быстро сваять небольшую иконку в консоли.

Или генерировать обои из цветной мозаики, где каждый квадратик имеет цвет, привязанный к какому-либо событию на ПК. То есть я вижу такие обои, или свой аватар, и по его квадратикам что-то узнаю. А данный формат для этого вполне подходил.

Но в общем вы правы, это не формат хранения, это формат обработки данных.

hikikomori ★★★
() автор топика
Последнее исправление: hikikomori (всего исправлений: 1)

convert: no images defined 'mario.png' @ error/convert.c/ConvertImageCommand/3325.

Если скачать картинку по вашей ссылке из фотостока, то всё более-менее работает:

# конвертируем скачанную картинку в список пикселей
magick mario.png -scale 16x16 mario.txt

# пиксели обратно в картинку
convert -background tan txt:mario.txt -filter point mario2.png
mydibyje ★★★
()
Ответ на: комментарий от mydibyje

Спасибо! Теперь можно пользоваться) Но проще перегнать матрицу картинки в .txt и раскрашивать уже описанные пиксели, чем писать руками. Да, -scale 16x16 без нужды лучше не указывать исходная картинка не из фотостока, нарисовал сам попикселям 20x20 и при скалинге получается фарш)

А не подскажите, как просто нарисовать одним массивом несколько пикселей? По одному неудобно: -draw 'point 3,2'. Может есть вариант указать список пикселей через -draw "path ?

Вот например как ниже с координатами линий, только вместо линий - точки?

# Используя две кривые Безье и координаты линий, рисуем фигуру (Анкх) на радиальном фоне.
magick -size 300x600  radial-gradient:pink1-Red1 -strokewidth 22 -stroke black -fill none -draw "bezier 155,27 20,40 110,218 150,270" -draw "bezier 154,27 280,40 190,218 149,270" -strokewidth 3 -fill black -draw "path 'M 10,255 150,266 290,255 290,300 162,286 172,561 127,561 137,286 10,300 10,255 '"  ankh-by-bezier.gif

Подытожу кейс «хранение картинки в ascii и её конвертация»:

  • Создаём спрайт mario.png из base64:
magick 'inline:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAA7EAAAO xAGVKw4bAAAA00lEQVQ4ja1UwRGDMAyTe7zLJmWUzMoodBO6gHmkhsRWcukVvYID kiKbiKoqbsTjTjIAmLq7IvXzwGHahJ5sUKBJKKhf3rcVAPB8pZ5BTihyEcxLomuD Fxhqyryk06WtDZ93LSB+bMqYvBtPBsQYA2FP3YPl2XUIAIpcsCZ5eRM18slvALyL CoFAu5EApCn7tsbx+hY0U55llmkYG7NefuhzKAVFUv1Mm8L+EgKWa5zDQbIWqiNn riuvID8g1r4c2Hi6Ghvg6sg/mqEIDv+9v2+/sQ8vtmAvY/Wf0QAAAABJRU5ErkJg gg==' mario.png

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

magick mario.png  mario.txt

пиксели обратно в картинку

convert -background tan txt:mario.txt -filter point mario2.png

Однако исходный файл и полученный из обратной конвертации не идентичны - формат пишет внутрь метаинфу:

colordiff <(unidump mario.png) <(unidump mario2.png)
hikikomori ★★★
() автор топика
Последнее исправление: hikikomori (всего исправлений: 2)
Ответ на: комментарий от tz4678_2

Да уж, но было это в домаккартистскую эпоху охоты на аватары…

А зачем использовали https://imagemagick.org/script/command-line-options.php#repage ?

Ради этого?

Use +repage to completely remove/reset the virtual canvas meta-data from the images.

В -crop +0+0 Это остатки чего-то другого или зачем?

hikikomori ★★★
() автор топика
Ответ на: комментарий от hikikomori

указать список пикселей через -draw "path ?

Можно указать координаты пикселей в примитиве полилиния

magick -size 10x10 xc:skyblue -fill none -stroke black -strokewidth 0 -draw "polyline 1,1 2,1 2,2 1,2" -draw "polyline 8,2 7,2" -stroke green -draw "polyline 1,5 2,6 3,7 6,7 7,6 8,5" smile.png
mydibyje ★★★
()
Ответ на: комментарий от Shadow

Это прекрасно и наглядно для пиксельарта в vim. Можно быстро нарисовать стрелку или спрайт. Мне очень понравилось, thanx! Кстати русская страница нагляднее пример показывает.

Применим к онтопику аналогично предыдущему примеру:

magick mario.png  mario.xpm
/* XPM */
static char *mario[] = {
/* columns rows colors chars-per-pixel */
"20 20 4 1 ",
"  c white",
". c red",
"X c blue",
"o c #F1D1B0",
/* pixels */
"                    ",
"                    ",
"       ....         ",
"      .........     ",
"      XXXXoo        ",
"     XooXooXoooo    ",
"     XooXXooXoooo   ",
"    XXXooooXXXXX    ",
"       oooooooo     ",
"    XXXX..XX    oo  ",
"  ooXXXX...XXXXooo  ",
"  ooo XX. ...XXXoo  ",
"  oo  .......   X   ",
"     ..........XX   ",
"    ...........XX   ",
"   XXX..   ....XX   ",
"   XXX              ",
"    XXX             ",
"                    ",
"                    "
};

И сразу видно, что это Марио.

А вот из xpm в графику получилось не сразу:

convert -background tan txt:mario.xpm -filter point mario3.png

txt: - лишнее. Правильно:

convert -background tan mario.xpm -filter point mario3.png

Кстати изменил белый на прозрачный в описателе цветов mario.xpm:

"  c None",

Отдельно показывает прозрачность, но при конвертации в картинку с указанным фоном холста - картинка не получает этого фона, а остаётся прозрачной.

hikikomori ★★★
() автор топика
Последнее исправление: hikikomori (всего исправлений: 2)
Ответ на: комментарий от mydibyje

Спасибо! То, что надо. Я конечно читал инструкцию по ссылке, но не очень понял смысл применение polyline. Что ещё неясно, так это -strokewidth 0 Я применял его для утолщения линий:

magick -size 500x500 xc:black -strokewidth 8 -stroke white -fill red -draw "path 'M 116,66 248,473 380,66 34,317 462,317 116,66 Z '" pentagram.gif

А тут даже 2 даёт какие-то тени с полутонами, а не удвоение пикселя.

magick -size 11x11 xc:tan -fill none -stroke blue -strokewidth 2 -draw "polyline 2,2 3,2 3,3 2,3" -draw "polyline 9,2 8,2" -stroke red -draw "polyline 2,6 3,7 4,8 7,8 8,7 9,6" smile.png
hikikomori ★★★
() автор топика
Последнее исправление: hikikomori (всего исправлений: 2)
Ответ на: комментарий от hikikomori

При нулевом значении лишние пиксели почти не красятся, такой вот.. хак(?). Если увеличивать толщину линии, включается то ли сглаживание (anti-aliasing), то ли еще что-то, что дает тени..

mydibyje ★★★
()
Ответ на: комментарий от mydibyje

Не подскажите, я так и не понял, зачем 2я пара цифр? Я понимаю, что поправки, но зачем?

magick logo: -gravity center -region '100x200-10+20' -negate wizNeg3.png

https://imagemagick.org/script/command-line-processing.php#geometry

Я же могу сразу указать 90x220. Зачем такая конструкция?

hikikomori ★★★
() автор топика
Ответ на: комментарий от hikikomori

Практический смысл - быстро сваять небольшую иконку в консоли.

много точек в одной строке писать устанешь

графические примитивы

А если попробовать объединить лучшее из миров растровой и векторной графики и написать простейший SVG? Вот пример с хабра:

<svg>  
<line x1="0" y1="0" x2="200" y2="200" stroke-width="1" stroke="rgb(0,0,0)"/>  
</svg>

Тут сразу готовая линия. Можно и фигур посложнее надобавлять, в той же статье есть примеры. Ну да, от «просто текстового файла» это отличается необходимостью открывать и закрывать теги, но можно один раз себе шаблончик наваять и подставлять в него что хочешь по мере надобности.

Нарисовал столько линий, сколько надо, думаю, svg и заливку позволит сделать (если нам для иконки) и конвертнул svg в растр любой подходящей программулиной. Гугл подсказывает, что это и imagemagick с доп.пакетами может.

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 4)
Ответ на: комментарий от hobbit

Формат xpm мне очень понравился. А вот svg без особой нужды применять не хочется, тем более для пиксель арта. Да и не люблю иерархический xml, тэги, куча мусора, читать неудобно.

curl -O https://www.w3.org/TR/SVG/images/paths/triangle01.svg

cat triangle01.svg 
<?xml version="1.0" standalone="no"?>
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <title>Example triangle01- simple example of a 'path'</title>
  <desc>A path that draws a triangle</desc>
  <rect x="1" y="1" width="398" height="398"
        fill="none" stroke="blue" />
  <path d="M 100 100 L 300 100 L 200 300 z"
        fill="red" stroke="blue" stroke-width="3" />
</svg>

А концепция path мне нравится, но для применения напрямую в im:

# Нарисовать ТРЕУГОЛЬНИК
magick -size 300x300 xc:black -strokewidth 8 -stroke white -fill red -draw "path 'M 50,70 L 240,70 L 150,250 Z'" triangle.gif
hikikomori ★★★
() автор топика
Ответ на: комментарий от hikikomori

А теперь другая трабла - хочу сгенерированное одной командой изображение отредактировать другой, но последняя просто перезаписывает входящий файл. Пробовал разные методы, не получается. Как?

ВОПРОС: Как наложить генерируемое изображение ПОВЕРХ имеющегося во входящем файле?

Неудачные попытки:

 magick -size 500x500 xc:none -draw "image over 0,0 0,0 'circle.gif'" -draw "image over 100,100 0,0 'pentagram.gif'" penta-circle.gif

magick pentagram.gif -strokewidth 8 -stroke white -draw "circle 248,248  110,60" pentaincircle.gif

magick gif:pentagram.gif -strokewidth 8 -stroke white -draw "circle 248,248  110,60"  pentaincircle.gif

hikikomori ★★★
() автор топика