GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Drucken Sie einen Halloween-Gruß mit ASCII-Grafik unter Linux

Vollfarbige ASCII-Kunst war früher unter DOS sehr beliebt, das den erweiterten ASCII-Zeichensatz und seine Sammlung von Zeichnungselementen nutzen konnte. Sie können Ihrem nächsten FreeDOS-Programm ein wenig visuelles Interesse verleihen, indem Sie ASCII-Grafiken als coolen „Willkommens“-Bildschirm oder als farbenfrohen „Beenden“-Bildschirm mit weiteren Informationen über das Programm hinzufügen.

Aber dieser Stil von ASCII-Kunst ist nicht nur auf FreeDOS-Anwendungen beschränkt. Sie können die gleiche Methode in einem Linux-Programm im Terminalmodus verwenden. Während Linux ncurses zur Steuerung des Bildschirms anstelle von Conio von DOS verwendet, lassen sich die verwandten Konzepte gut auf Linux-Programme anwenden. Dieser Artikel befasst sich mit der Generierung farbiger ASCII-Grafiken aus einem C-Programm.

Weitere Linux-Ressourcen

  • Spickzettel für Linux-Befehle
  • Spickzettel für fortgeschrittene Linux-Befehle
  • Kostenloser Online-Kurs:RHEL Technical Overview
  • Spickzettel für Linux-Netzwerke
  • SELinux-Spickzettel
  • Spickzettel für allgemeine Linux-Befehle
  • Was sind Linux-Container?
  • Unsere neuesten Linux-Artikel

Eine ASCII-Grafikdatei

Sie können eine Vielzahl von Werkzeugen verwenden, um Ihre ASCII-Kunst zu zeichnen. Für dieses Beispiel habe ich eine alte DOS-Anwendung namens TheDraw verwendet, aber unter Linux finden Sie moderne Open-Source-ASCII-Kunstprogramme wie Moebius (Apache-Lizenz) oder PabloDraw (MIT-Lizenz). Es spielt keine Rolle, welches Tool Sie verwenden, solange Sie wissen, wie die gespeicherten Daten aussehen.

Hier ist ein Teil einer Beispiel-ASCII-Art-Datei, die als C-Quellcode gespeichert ist. Beachten Sie, dass das Code-Snippet einige Werte definiert:IMAGEDATA_WIDTH und IMAGEDATA_DEPTH Definieren Sie die Anzahl der Spalten und Zeilen auf dem Bildschirm. In diesem Fall handelt es sich um ein 80 x 25 ASCII-Bild. IMAGEDATA_LENGTH definiert die Anzahl der Einträge in den IMAGEDATA Reihe. Jedes Zeichen im ASCII-Grafikbildschirm kann durch zwei Datenbytes dargestellt werden:Das anzuzeigende Zeichen und ein Farbattribut, das sowohl die Vordergrund- als auch die Hintergrundfarbe für das Zeichen enthält. Bei einem 80x25-Bildschirm, bei dem jedes Zeichen mit einem Attribut gepaart ist, enthält das Array 4000 Einträge (das sind 80 * 25 * 2 =4000).

#define IMAGEDATA_WIDTH 80
#define IMAGEDATA_DEPTH 25
#define IMAGEDATA_LENGTH 4000
unsigned char IMAGEDATA [] ={
    '.', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
    ' ', 0x08,  ' ', 0x08,  '.', 0x0F,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
    ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  '.', 0x0F,
    ' ', 0x08,  ' ' , 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,
    ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,  ' ', 0x08,

und so weiter für den Rest des Arrays.

Um diese ASCII-Grafik auf dem Bildschirm anzuzeigen, müssen Sie ein kleines Programm schreiben, das das Array liest und jedes Zeichen mit den richtigen Farben ausgibt.

Ein Farbattribut festlegen

Das Farbattribut in dieser ASCII-Grafikdatei definiert sowohl die Hintergrund- als auch die Vordergrundfarbe in einem einzelnen Byte, dargestellt durch Hexadezimalwerte wie 0x08 oder 0x6E . Hexadezimal stellt sich als kompakte Möglichkeit heraus, ein Farbpaar wie dieses auszudrücken.

Zeichenmodussysteme wie ncurses unter Linux oder conio unter DOS können nur sechzehn Farben darstellen. Das sind sechzehn mögliche Textfarben und acht Hintergrundfarben. Das Zählen von sechzehn Werten (von 0 bis 15) in Binärform erfordert nur vier Bits:

  • 1111 ist 16 in binär

Und praktischerweise kann Hexadezimal 0 bis 15 mit einem einzigen Zeichen darstellen:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E und F. Also der Wert F hexadezimal ist die Zahl 15 oder 1111 im Binärformat.

Mit Farbpaaren können Sie sowohl die Hintergrund- als auch die Vordergrundfarbe in einem einzigen Byte von acht Bit codieren. Das sind vier Bits für die Textfarbe (0 bis 15 oder 0 bis F im Hexadezimalformat) und drei Bits für die Hintergrundfarbe (0 bis 7 oder 0 bis E im Hexadezimalformat). Das Restbit im Byte wird hier nicht verwendet, also können wir es ignorieren.

Um das Farbpaar oder Attribut in Farbwerte umzuwandeln, die Ihr Programm verwenden kann, müssen Sie eine Bitmaske verwenden, um nur die Bits anzugeben, die für die Text- oder Hintergrundfarbe verwendet werden. Mit dem OpenWatcom C-Compiler unter FreeDOS können Sie diese Funktion schreiben, um die Farben entsprechend aus dem Farbattribut festzulegen:

void
textattr(int newattr)
{
  _settextcolor(newattr &15); /* 0000xxxx */
  _setbkcolor((newatr>> 4) &7); /* 0xxx0000 */
}

Die _settextcolor Funktion setzt nur die Textfarbe und den _setbkcolor Funktion setzt die Hintergrundfarbe. Beide sind in graph.h definiert . Beachten Sie, dass textattr, da das Farbattribut sowohl die Hintergrundfarbe als auch die Vordergrundfarbe in einem einzelnen Bytewert enthält Funktion verwendet & (binäres UND), um eine Bitmaske festzulegen, die nur die letzten vier Bits im Attribut isoliert. Dort speichert das Farbpaar die Werte 0 bis 15 für die Vordergrundfarbe.

Um die Hintergrundfarbe zu erhalten, führt die Funktion zunächst eine Bitverschiebung durch, um die Bits nach rechts zu „schieben“. Dadurch werden die „oberen“ Bits in den „unteren“ Bitbereich verschoben, also alle Bits wie 0xxx0000 zu 00000xxx werden stattdessen. Wir können eine andere Bitmaske mit 7 verwenden (binär 0111 ), um den Hintergrundfarbwert auszuwählen.

ASCII-Grafik anzeigen

Die IMAGEDATA Das Array enthält den gesamten ASCII-Grafikbildschirm und die Farbwerte für jedes Zeichen. Um das ASCII-Bild auf dem Bildschirm anzuzeigen, muss Ihr Programm das Array scannen, das Farbattribut festlegen und dann den Bildschirm zeichenweise anzeigen.

Lassen Sie uns am unteren Rand des Bildschirms Platz für eine separate Nachricht oder Aufforderung an den Benutzer. Das heißt, anstatt alle 25 Zeilen eines 80-Spalten-ASCII-Bildschirms anzuzeigen, möchte ich nur die ersten 24 Zeilen anzeigen.

  /* eine Zeile weniger als 80 x 25 ausgeben, die darin enthalten ist:
     80 x 24 x 2 =3840 */

  für (pos =0; pos <3840; pos +=2) {
...
  }

Innerhalb des for Schleife müssen wir die Farben einstellen und dann das Zeichen drucken. Der OpenWatcom C Compiler bietet eine Funktion _outtext Text mit den aktuellen Farbwerten anzuzeigen. Dies erfordert jedoch die Übergabe eines Strings und wäre ineffizient, wenn wir jedes Zeichen einzeln verarbeiten müssten, falls jedes Zeichen in einer Zeile eine andere Farbe erfordert.

Stattdessen hat OpenWatcom eine ähnliche Funktion namens _outmem Damit können Sie angeben, wie viele Zeichen angezeigt werden sollen. Für jeweils ein Zeichen können wir einen Zeiger auf einen Zeichenwert in IMAGEDATA bereitstellen array und sag _outtext nur ein Zeichen zu zeigen. Dadurch wird das Zeichen mit den aktuellen Farbattributen angezeigt, was wir brauchen.

  for (pos =0; pos <3840; pos +=2) {
    ch =&IMAGEDATA[pos]; /* Zeigerzuweisung */
    attr =IMAGEDATA[pos + 1];
 
    textattr(attr);
    _outmem(ch, 1);
  }

Dies hat for aktualisiert loop setzt das Zeichen ch durch Zuweisen eines Zeigers in die IMAGEDATA Reihe. Als nächstes setzt die Schleife die Textattribute und zeigt dann das Zeichen mit _outmem an .

Alles zusammenfügen

Mit dem textattr Funktion und den for -Schleife verwenden, um das Array zu verarbeiten, können wir ein vollständiges Programm schreiben, um den Inhalt einer ASCII-Art-Datei anzuzeigen. Speichern Sie für dieses Beispiel das ASCII-Bild als imgdata.inc und fügen Sie es mit einem #include in die Quelldatei ein Aussage.

#include 
#include
#include

#include "imgdata.inc"

void
textattr(int newattr)
{
  _settextcolor(newattr &15); /* 0000xxxx */
  _setbkcolor((newatr>> 4) &7); /* 0xxx0000 */
}

int
main()
{
  char *ch;
  int attr;
int pos;

  if (_setvideomode(_TEXTC80) ==0) {
    fputs("Fehler beim Einstellen des Videomodus", stderr);
    return 1;
  }

  /* Array zeichnen */

  _settextposition(1, 1); /* oben links */

  /* eine Zeile weniger als 80 x 25 ausgeben:
     80 x 24 x 2 =3840 */

  für ( pos =0; pos <3840; pos +=2) {
    ch =&IMAGEDATA[pos]; /* Zeigerzuweisung */
    attr =IMAGEDATA[pos + 1];

    textattr(attr);
    _outmem(ch, 1);
  }

  /* fertig */

  _settextposition(25, 1); /* unten links */

  textattr(0x0f);
  _outtext("Zum Beenden eine beliebige Taste drücken");

  getch();

  textattr(0x00);
  return 0;
}

Kompilieren Sie das Programm mit dem OpenWatcom C Compiler unter FreeDOS, und Sie erhalten ein neues Programm, das diese Feiertagsnachricht anzeigt:

Allen ein frohes Halloween!

Laden Sie die INC-Code-Datei hier herunter.

Laden Sie die C-Code-Datei hier herunter.

imgdata.inc_.txt hallown.c.txt
Linux
  1. Linux-Paketverwaltung mit apt

  2. So analysieren und verschönern Sie JSON mit Linux-Befehlszeilentools

  3. JQ-Befehl in Linux mit Beispielen

  4. Linux – Wie kombiniere ich den Baum mit der Verzeichnisgröße?

  5. So drucken Sie eine Reihe von IP-Adressen mit dem Linux-Befehl seq

Stellen Sie ein altes MacBook mit Linux wieder her

wc Linux-Befehl mit Beispielen

Linux-IP-Befehl mit Beispielen

15 Linux-PS-Befehl mit Beispielen

Zeitstempel mit Ping-Befehlsausgabe in Linux drucken

Aufbau von 0verkill auf Windows 10 Subsystem für Linux – 2D-ASCII-Art-Deathmatch-Spiel