makeArt | simple ASCII-Art Grafikbibliothek

  • Code
    [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    []                                                                  []
    []  []      []  [][][]  []  []  [][][]      [][][]  [][][]  [][][]  []
    []  [][]  [][]  []  []  []  []  []          []  []  []  []    []    []
    []  []  []  []  [][][]  [][]    [][][]      [][][]  [][][]    []    []
    []  []      []  []  []  []  []  []          []  []  [][]      []    []
    []  []      []  []  []  []  []  [][][]      []  []  []  []    []    []
    []                                                                  []
    [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

    Schönen guten Abend AutoIt Community! :)
    Ich möchte euch meine makeArt UDF vorstellen, mit dieser ist es möglich einfach & schnell ASCII-Art Bilder zu erstellen. Zwar unterstützt diese UDF derzeitig nur die Grundkörper (Punkt, Linie, Kreis, Dreieck und Viereck) aber immerhin lassen sich damit schon ein paar schöne Bilder zaubern.

    Ich wollte mir mal ansehen wie die Grafikbibliotheken arbeiten, dafür habe ich meinen besten Freund Google beansprucht und bin dadurch auf den Begriff „Rasterung“ gestoßen. Das Thema fand ich so interessant, dass ich dies einmal unbedingt programmieren wollte. Jedoch war mir der Teil wo die Bilder auf den Bildschirm ausgegeben werden zu umständlich, daher habe ich mir gedacht ich nehme die einfachste Möglichkeit und arbeite einfach mit Char's. So wurde meine kleine UDF in die Welt gesetzt.

    Zwar ist diese in Ihren Möglichkeiten noch begrenzt, jedoch habe ich vor in naher Zukunft daran weiter zu arbeiten und weitere Funktionen zu schreiben. Sie soll alles können was auch andere große Grafikbibliotheken (wie z.B. GDI oder GDI+) können. Zwar hat dies praktisch gesehen keinen Sinn, bietet mir jedoch eine Möglichkeit mich ein wenig in die Materie einzuarbeiten und zu verstehen wie Grafikbibliotheken Bilder generieren. Zudem bin ich auch auf die abstrakte Idee gekommen ein Spiel mit schöner ASCII Art Grafik zu programmieren, daher hat diese UDF zumindest bei mir auch einen Verwendungszweck. ;D

    Soa, da ich nun viel über meine Motivation geschrieben habe möchte ich euch die UDF auch nicht länger vorenthalten. Feedback und Verbesserungsvorschläge sind gerne gesehen. Die Funktionsbeschreibungen befinden sich in der UDF.

    Spoiler anzeigen
    [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    ; [] []
    ; [] [] [] [][][] [] [] [][][] [][][] [][][] [][][] []
    ; [] [][] [][] [] [] [] [] [] [] [] [] [] [] []
    ; [] [] [] [] [][][] [][] [][][] [][][] [][][] [] []
    ; [] [] [] [] [] [] [] [] [] [] [][] [] []
    ; [] [] [] [] [] [] [] [][][] [] [] [] [] [] []
    ; [] []
    ; [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; makeArt_Char
    ; makeArt_Circle
    ; makeArt_Coord
    ; makeArt_Create
    ; makeArt_Line
    ; makeArt_Plane
    ; makeArt_Point
    ; makeArt_Quadrangle
    ; makeArt_Screen
    ; makeArt_Triangle

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #comments-start | +++ UDF-Beschreibung +++

    [/autoit] [autoit][/autoit] [autoit]

    $makeArt_Screen
    Dies ist eine vorgefertigter Zeichenbereich mit der Größe von 1*1 Elementen.
    Diese Variable kann nach belieben überschrieben und genutzt werden.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Char($sChar = Default)
    Mit dieser Funktion können die Standardzeichen geändert werden.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Circle(ByRef $asScreen, $nX, $nY, $nR, $vChar = makeArt_Char)
    Zeichnet einen Kreis auf dem Bildschirm $asScreen mit dem Mittelpunkt $nX und $nY und dem Radius $nR.
    Falls $vChar angegeben wird, wird statt dem Standardzeichen mit den angegeben Zeichen der Kreis gezeichnet.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Coord(ByRef $asScreen, $nX, $nY, $iFrom = Default, $iMode = $makeArt_Get)
    Verändert den Mittelpunkt und die Achsenausrichtung des Koordinatensystems auf welches gezeichnet wird.
    Alle Koordinaten der Zeichenfunktionen werden relativ vom Mittelpunkt des Koordinatensystems angegeben.
    Mit $nX und $nY kann der mittelpunkt verändert werden. -1 gibt dabei die Mitte der Zeichenbereichs $asScreen an.
    Die Variable $iFrom gibt dabei die Achsenausrichtung des Koordinatensystems an. Dazu sind folgende Konstanten vorgesehen:
    $makeArt_TopLeft :> Die X-Achse zeigt nach Rechts, die Y-Achse zeigt nach Unten
    $makeArt_TopRight :> Die X-Achse zeigt nach Links, die Y-Achse zeigt nach Unten
    $makeArt_BottomLeft :> Die X-Achse zeigt nach Rechts, die Y-Achse zeigt nach Oben
    $makeArt_BottomRight :> Die X-Achse zeigt nach Links, die Y-Achse zeigt nach Oben
    Mit der Variable $iMode kann angegeben werden, ob die Koordinaten ausgegeben oder gesetzt werden sollen. Dazu stehen 2 Konstanten zur Verfügung:
    $makeArt_Get :> Gibt die absoluten Koordinaten aus
    $makeArt_Set :> Setzt den neuen Mittelpunkt des Koordinatensystems

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Create(ByRef $asScreen)
    Erstellt das gezeichnete Bild und gibt dieses als String zurück.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Line(ByRef $asScreen, $nX1, $nY1, $nX2, $nY2, $vChar = makeArt_Char)
    Zeichnet eine Linie auf dem Bildschirm $asScreen von ($nX1 | $nY1) nach ($nX2 | $nY2).
    Falls $vChar angegeben wird, wird statt dem Standardzeichen mit den angegeben Zeichen die Linie gezeichnet.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Plane(ByRef $asScreen, $nX, $nY, ByRef $asPlane)
    Zeichnet ein Zeichenbereich $asPlane in ein anderen Zeichenbereich $asScreen an dem Punkt ($nX | $nY) hinein.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Point(ByRef $asScreen, $nX, $nY, $vChar = makeArt_Char)
    Zeichnet einen Punkt auf dem Bildschirm $asScreen an dem Punkt ($nX | $nY).

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Quadrangle(ByRef $asScreen, $nX, $nY, $nWidth, $nHeight, $vChar = makeArt_Char)
    Zeichnet ein Viereck auf dem Bildschirm $asScreen an dem Punkt ($nX | $nY) mit der Breite $nWidth und der Höhe $nHeight.
    Falls $vChar angegeben wird, wird statt dem Standardzeichen mit den angegeben Zeichen das Viereck gezeichnet.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Screen($iWidth, $iHeight, $sChar = ' ')
    Erstellt einen Zeichenbereich mit der Breite $iWidth und der Höhe $iHeight.
    Falls $sChar angegeben wird dieser mit den Zeichen gefüllt.

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Triangle(ByRef $asScreen, $nX1, $nY1, $nX2, $nY2, $nX3, $nY3, $vChar = makeArt_Char)
    Zeichnet ein Dreieck auf dem Bildschirm $asScreen mit den drei Eckpunkten ($nX1 | $nY1), ($nX2 | $nY2) und ($nX3 | $nY3).
    Falls $vChar angegeben wird, wird statt dem Standardzeichen mit den angegeben Zeichen das Dreieck gezeichnet.

    [/autoit] [autoit][/autoit] [autoit]

    #comments-end

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $makeArt_Screen = makeArt_Screen(1, 1)
    Global Enum $makeArt_TopLeft, $makeArt_TopRight, $makeArt_BottomLeft, $makeArt_BottomRight, $makeArt_Get, $makeArt_Set

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Char($sChar = Default)
    Local Static $makeArt_Char = '+'
    $makeArt_Char = (($sChar <> Default) ? ($sChar) : ($makeArt_Char))
    Return $makeArt_Char
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Circle(ByRef $asScreen, $nX, $nY, $nR, $vChar = makeArt_Char)
    Local Static $fArc = ATan(1) * 4 / 180
    Local $i

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 360
    makeArt_Point($asScreen, Sin($i / $fArc) * $nR + $nX, Cos($i / $fArc) * $nR + $nY, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Coord(ByRef $asScreen, $nX, $nY, $iFrom = Default, $iMode = $makeArt_Get)
    Local Static $makeArt_nX, $makeArt_nY, $makeArt_iFrom = $makeArt_TopLeft
    Local $aiCoord[2]

    [/autoit] [autoit][/autoit] [autoit]

    Switch $iMode
    Case $makeArt_Get
    If $iFrom = Default Then $iFrom = $makeArt_iFrom
    $aiCoord[0] = ($iFrom = $makeArt_TopRight Or $iFrom = $makeArt_BottomRight) ? (UBound($asScreen, 1) - Round($nX + (($makeArt_nX = -1) ? ((UBound($asScreen, 1) -1) / 2) : ($makeArt_nX))) -1) : (Round($nX + (($makeArt_nX = -1) ? ((UBound($asScreen, 1) -1) / 2) : ($makeArt_nX))))
    $aiCoord[1] = ($iFrom = $makeArt_BottomLeft Or $iFrom = $makeArt_BottomRight) ? (UBound($asScreen, 2) - Round($nY + (($makeArt_nY = -1) ? ((UBound($asScreen, 2) -1) / 2) : ($makeArt_nY))) -1) : (Round($nY + (($makeArt_nY = -1) ? ((UBound($asScreen, 2) -1) / 2) : ($makeArt_nY))))
    Return $aiCoord
    Case $makeArt_Set
    $makeArt_nX = $nX
    $makeArt_nY = $nY
    $makeArt_iFrom = $iFrom
    EndSwitch
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Create(ByRef $asScreen)
    Local $i, $n, $sRet

    [/autoit] [autoit][/autoit] [autoit]

    For $n = 0 To UBound($asScreen, 2) -1
    For $i = 0 To UBound($asScreen, 1) -1
    $sRet &= $asScreen[$i][$n]
    Next
    $sRet &= @CRLF
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return StringTrimRight($sRet, 1)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Line(ByRef $asScreen, $nX1, $nY1, $nX2, $nY2, $vChar = makeArt_Char)
    Local $b = (Abs($nX2 - $nX1) > Abs($nY2 - $nY1))
    Local $iS = (($b) ? ((($nX2 - $nX1) < 0) ? (-1) : (1)) : ((($nY2 - $nY1) < 0) ? (-1) : (1)))
    Local $nM = $iS * (($b) ? (($nY2 - $nY1) / ($nX2 - $nX1)) : (($nX2 - $nX1) / ($nY2 - $nY1)))
    Local $nY = (($b) ? ($nY1) : ($nX1))
    Local $nX

    [/autoit] [autoit][/autoit] [autoit]

    For $nX = (($b) ? ($nX1) : ($nY1)) To (($b) ? ($nX2) : ($nY2)) Step $iS
    makeArt_Point($asScreen, (($b) ? ($nX) : ($nY)), (($b) ? ($nY) : ($nX)), ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    $nY += $nM
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Plane(ByRef $asScreen, $nX, $nY, ByRef $asPlane)
    Local $i, $n

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To UBound($asPlane, 1) -1
    For $n = 0 To UBound($asPlane, 1) -1
    makeArt_Point($asScreen, $i + $nX, $n + $nY, $asPlane[$i][$n])
    Next
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Point(ByRef $asScreen, $nX, $nY, $vChar = makeArt_Char)
    Local $aiCoord = makeArt_Coord($asScreen, $nX, $nY)
    $asScreen[$aiCoord[0]][$aiCoord[1]] = ((IsFunc($vChar) ? ($vChar()) : ($vChar)))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Quadrangle(ByRef $asScreen, $nX, $nY, $nWidth, $nHeight, $vChar = makeArt_Char)
    Local $nX2 = $nX + $nWidth
    Local $nY2 = $nY + $nHeight
    makeArt_Line($asScreen, $nX, $nY, $nX2, $nY, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    makeArt_Line($asScreen, $nX2, $nY, $nX2, $nY2, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    makeArt_Line($asScreen, $nX2, $nY2, $nX, $nY2, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    makeArt_Line($asScreen, $nX, $nY2, $nX, $nY, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Screen($iWidth, $iHeight, $sChar = ' ')
    Local $asScreen[$iWidth +1][$iHeight +1], $i, $n

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To $iWidth
    For $n = 0 To $iHeight
    $asScreen[$i][$n] = $sChar
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $asScreen
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func makeArt_Triangle(ByRef $asScreen, $nX1, $nY1, $nX2, $nY2, $nX3, $nY3, $vChar = makeArt_Char)
    makeArt_Line($asScreen, $nX1, $nY1, $nX2, $nY2, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    makeArt_Line($asScreen, $nX2, $nY2, $nX3, $nY3, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    makeArt_Line($asScreen, $nX3, $nY3, $nX1, $nY1, ((IsFunc($vChar) ? ($vChar()) : ($vChar))))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit]

    Dazu auch einen kleinen Beispielcode:

    Spoiler anzeigen
    [autoit]

    #include "makeArt.au3"

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Coord($makeArt_Screen, -1, -1, $makeArt_TopLeft, $makeArt_Set)
    makeArt_Char('**')
    $makeArt_Screen = makeArt_Screen(20, 20, ' ')

    [/autoit] [autoit][/autoit] [autoit]

    makeArt_Point($makeArt_Screen, 0, 0, '++')
    makeArt_Circle($makeArt_Screen, 0, 0, 5)
    makeArt_Quadrangle($makeArt_Screen, -10, -10, 20, 20, '##')

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(makeArt_Create($makeArt_Screen))

    [/autoit]

    Ich wünsche viel Spaß! :P

  • Hi,

    Zitat

    und bin dadurch auf den Begriff „Rasterung“ gestoßen.

    Zitat

    edoch war mir der Teil wo die Bilder auf den Bildschirm ausgegeben werden zu umständlich


    Da fällt mir nur eins dazu ein :D

  • Jaja, kaum macht da wer was interessantes muss Andy mit seiner eigenen Arbeit pralen. :D
    Und dann noch mit nem Skript aus 2010, ich weiß ja nicht so recht. :p
    Gelungenes Skript! Sieht wirklich interessant aus. ^^

    Einmal editiert, zuletzt von Yjuq (1. August 2014 um 08:41)

  • Hi,

    Zitat

    Jaja, kaum macht da wer was interessantes muss Andy mit seiner eigenen Arbeit pralen. :D

    Ich habe mal zu einer Kollegin gesagt:" Wir sind nicht arrogant, wir wissen, dass wir gut sind!" :P

    Aber die Scripte sind doch garnicht so weit voneinander entfernt.
    Lies ein beliebiges Bild ein, lass einen Kantenfilter drüberlaufen -> schwarze Kanten auf weißem Grund
    Rastere das Bild in der Größe deiner gewünschten Ascii-Art in "Kacheln" (Tiles)
    Jetzt musst du "nur noch" für jede einzelne Kachel das darin vorkommende Kantenstück einem Ascii-Zeichen zuordnen.
    Dazu würde ich zu jedem Ascii-Zeichen eine entsprechende "Kachel" entwerfen und einfach mit den erzeugten Kacheln auf größte Übereinstimmung der "Pixel" abgleichen.

    Danach noch mit der "Farbe" der Kachel einfärben, und du hast ein extrem komprimiertes "Bild" in Ascii-Art 8o