Я тут под свои нужды накидал простенький редактор битмапок, который позволит кабанчиком рисовать небольшие пиктограммки. Получилось довольно неплохо и я решил поделиться им с сообществом. Код простой, поэтому легко будет подстроить под свои нужны.
Перемещение фукуса стрелочками. Для рисования/стирания пикселя используется пробел. По нажатию кнопки «Dump» в консоль выплёвывается последовательность 0 и 1 в виде текста, которую дальше можете сконвертировать в тот формат, который вам нужен.
Пример использования https://0x0.st/Kf8v.png
#!/usr/bin/wish
##########################
### settings start ###
set bitmapWidth 32
set bitmapHeight 32
### settings end ###
##########################
set currentFocusX 0
set currentFocusY 0
set verticalSymmetry 0
set horizontalSymmetry 0
set diagonalSymmetry 0
ttk::style layout pixel.TCheckbutton {
Checkbutton.indicator
Checkbutton.focus
}
proc focusUp { } {
if { $::currentFocusY > 0 } {
incr ::currentFocusY -1
}
focus .checkboxArea.pixelr${::currentFocusY}c${::currentFocusX}
}
proc focusDown { } {
if { $::currentFocusY < [expr $::bitmapHeight - 1] } {
incr ::currentFocusY
}
focus .checkboxArea.pixelr${::currentFocusY}c${::currentFocusX}
}
proc focusLeft { } {
if { $::currentFocusX > 0 } {
incr ::currentFocusX -1
}
focus .checkboxArea.pixelr${::currentFocusY}c${::currentFocusX}
}
proc focusRight { } {
if { $::currentFocusX < [expr $::bitmapWidth - 1] } {
incr ::currentFocusX
}
focus .checkboxArea.pixelr${::currentFocusY}c${::currentFocusX}
}
proc shiftUp { } {
for { set rowNo 1 } { $rowNo < $::bitmapHeight } { incr rowNo } {
set rowNoTo [expr $rowNo - 1]
for { set colNo 0 } { $colNo < $::bitmapWidth } { incr colNo } {
set ::pixelr${rowNoTo}c${colNo} [ set ::pixelr${rowNo}c${colNo} ]
}
}
}
proc shiftLeft { } {
for { set colNo 1 } { $colNo < $::bitmapWidth } { incr colNo } {
set colNoTo [ expr $colNo - 1 ]
for { set rowNo 0 } { $rowNo < $::bitmapHeight } { incr rowNo } {
set ::pixelr${rowNo}c${colNoTo} [ set ::pixelr${rowNo}c${colNo} ]
}
}
}
proc shiftRight { } {
if { $::bitmapWidth < 2 } return
for { set colNo [expr $::bitmapWidth - 2] } { $colNo >= 0 } { incr colNo -1 } {
set colNoTo [ expr $colNo + 1 ]
for { set rowNo 0 } { $rowNo < $::bitmapHeight } { incr rowNo } {
set ::pixelr${rowNo}c${colNoTo} [ set ::pixelr${rowNo}c${colNo} ]
}
}
}
proc shiftDown { } {
if { $::bitmapHeight < 2 } return
for { set rowNo [expr $::bitmapHeight - 2] } { $rowNo >= 0 } { incr rowNo -1 } {
set rowNoTo [ expr $rowNo + 1 ]
for { set colNo 0 } { $colNo < $::bitmapWidth } { incr colNo } {
set ::pixelr${rowNoTo}c${colNo} [ set ::pixelr${rowNo}c${colNo}]
}
}
}
proc setAllPixelsValue { value } {
for { set rowNo 0 } { $rowNo < $::bitmapHeight } { incr rowNo } {
for { set colNo 0 } { $colNo < $::bitmapWidth } { incr colNo } {
set ::pixelr${rowNo}c${colNo} $value
}
}
}
proc verticalSymmetryHandler { rowNo colNo } {
set mirrorCol [ expr $::bitmapWidth - $colNo - 1 ]
set ::pixelr${rowNo}c${mirrorCol} [ set ::pixelr${rowNo}c${colNo} ]
}
proc horizontalSymmetryHandler { rowNo colNo } {
set mirrorRow [ expr $::bitmapHeight - $rowNo - 1 ]
set ::pixelr${mirrorRow}c${colNo} [ set ::pixelr${rowNo}c${colNo} ]
}
proc diagonalSymmetryHandler { rowNo colNo } {
set diagonalRow [ expr $::bitmapWidth - $rowNo - 1 ]
set diagonalCol [ expr $::bitmapWidth - $colNo - 1 ]
set ::pixelr${diagonalRow}c${diagonalCol} [ set ::pixelr${rowNo}c${colNo} ]
}
proc symmetryHandler { rowNo colNo } {
if { $::verticalSymmetry } {
verticalSymmetryHandler $rowNo $colNo
}
if { $::horizontalSymmetry } {
horizontalSymmetryHandler $rowNo $colNo
}
if { $::diagonalSymmetry } {
diagonalSymmetryHandler $rowNo $colNo
}
}
proc dumpPixelmap { } {
puts ""
for { set rowNo 0 } { $rowNo < $::bitmapHeight } { incr rowNo } {
for { set colNo 0 } { $colNo < $::bitmapWidth } { incr colNo } {
puts -nonewline [set ::pixelr${rowNo}c${colNo}]
}
}
puts ""
puts ""
}
proc buildCheckboxArea { } {
for { set rowNo 0 } { $rowNo < 32 } { incr rowNo } {
for { set colNo 0 } { $colNo < 32 } { incr colNo } {
ttk::checkbutton .checkboxArea.pixelr${rowNo}c${colNo} -style pixel.TCheckbutton -variable pixelr${rowNo}c${colNo} -command "symmetryHandler $rowNo $colNo"
grid .checkboxArea.pixelr${rowNo}c${colNo} -row $rowNo -column $colNo
set ::pixelr${rowNo}c${colNo} 0
}
}
}
proc buildGui { } {
set buttonsPaddingY 30
# window layout
ttk::frame .checkboxArea
ttk::frame .controlPanel
grid .checkboxArea -row 0 -column 0 -padx 10 -pady 10
grid .controlPanel -row 0 -column 1 -padx 10 -pady 10
#chechbox area build
buildCheckboxArea
#control panel
#sel clear
ttk::button .controlPanel.allClear -text "All clear" -command { setAllPixelsValue 0 }
ttk::button .controlPanel.allSet -text "All set" -command { setAllPixelsValue 1 }
grid .controlPanel.allClear -row 0 -column 0
grid .controlPanel.allSet -row 10 -column 0
#shift panel
ttk::frame .controlPanel.shift
grid .controlPanel.shift -row 20 -column 0 -pady $buttonsPaddingY
ttk::button .controlPanel.shift.up -text "/\\" -command shiftUp
ttk::button .controlPanel.shift.left -text "<" -command shiftLeft
ttk::button .controlPanel.shift.right -text ">" -command shiftRight
ttk::button .controlPanel.shift.down -text "\\/" -command shiftDown
grid .controlPanel.shift.up -row 0 -column 1
grid .controlPanel.shift.left -row 1 -column 0
grid .controlPanel.shift.right -row 1 -column 2
grid .controlPanel.shift.down -row 2 -column 1
#symmetry settings
ttk::frame .controlPanel.symmetry
grid .controlPanel.symmetry -row 30 -column 0 -pady $buttonsPaddingY
ttk::checkbutton .controlPanel.symmetry.vertical -text "Вертикальная симметрия" -variable verticalSymmetry
ttk::checkbutton .controlPanel.symmetry.horizontal -text "Горизонтальная симметрия" -variable horizontalSymmetry
ttk::checkbutton .controlPanel.symmetry.diagonal -text "Диагональная симметрия" -variable diagonalSymmetry
grid .controlPanel.symmetry.vertical -pady 5
grid .controlPanel.symmetry.horizontal -pady 5
grid .controlPanel.symmetry.diagonal -pady 5
#dump
ttk::button .controlPanel.dump -text "Dump" -command { dumpPixelmap }
grid .controlPanel.dump -row 100 -column 0 -pady $buttonsPaddingY
}
buildGui
bind . <KeyPress-Up> { focusUp }
bind . <KeyPress-Left> { focusLeft }
bind . <KeyPress-Down> { focusDown }
bind . <KeyPress-Right> { focusRight }




