Frage Zeigen Sie ein Bild in einer Konsolenanwendung an


Ich habe eine Konsolenanwendung, die Bilder verwaltet. Jetzt brauche ich etwas wie eine Vorschau der Bilder in der Konsolenanwendung. Gibt es eine Möglichkeit, sie in der Konsole anzuzeigen?

Hier ist ein Vergleich der aktuellen zeichenbasierten Antworten:

Eingang:

enter image description here

Ausgabe:

enter image description here

enter image description here

enter image description here

enter image description here


75
2017-11-05 07:08


Ursprung


Antworten:


Ich spielte weiter mit Code von @DieterMeemken. Ich habe die vertikale Auflösung halbiert und Dithering über ▒▓ hinzugefügt. Auf der linken Seite ist Dieter Meemken Ergebnis, auf der rechten Seite mein. Unten ist das Originalbild so skaliert, dass es dem Ausgang entspricht. Output result Obwohl die Konvertierungsfunktion von Malwyns beeindruckend ist, werden nicht alle grauen Farben verwendet.

static int[] cColors = { 0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080, 0x808000, 0xC0C0C0, 0x808080, 0x0000FF, 0x00FF00, 0x00FFFF, 0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF };

public static void ConsoleWritePixel(Color cValue)
{
    Color[] cTable = cColors.Select(x => Color.FromArgb(x)).ToArray();
    char[] rList = new char[] { (char)9617, (char)9618, (char)9619, (char)9608 }; // 1/4, 2/4, 3/4, 4/4
    int[] bestHit = new int[] { 0, 0, 4, int.MaxValue }; //ForeColor, BackColor, Symbol, Score

    for (int rChar = rList.Length; rChar > 0; rChar--)
    {
        for (int cFore = 0; cFore < cTable.Length; cFore++)
        {
            for (int cBack = 0; cBack < cTable.Length; cBack++)
            {
                int R = (cTable[cFore].R * rChar + cTable[cBack].R * (rList.Length - rChar)) / rList.Length;
                int G = (cTable[cFore].G * rChar + cTable[cBack].G * (rList.Length - rChar)) / rList.Length;
                int B = (cTable[cFore].B * rChar + cTable[cBack].B * (rList.Length - rChar)) / rList.Length;
                int iScore = (cValue.R - R) * (cValue.R - R) + (cValue.G - G) * (cValue.G - G) + (cValue.B - B) * (cValue.B - B);
                if (!(rChar > 1 && rChar < 4 && iScore > 50000)) // rule out too weird combinations
                {
                    if (iScore < bestHit[3])
                    {
                        bestHit[3] = iScore; //Score
                        bestHit[0] = cFore;  //ForeColor
                        bestHit[1] = cBack;  //BackColor
                        bestHit[2] = rChar;  //Symbol
                    }
                }
            }
        }
    }
    Console.ForegroundColor = (ConsoleColor)bestHit[0];
    Console.BackgroundColor = (ConsoleColor)bestHit[1];
    Console.Write(rList[bestHit[2] - 1]);
}


public static void ConsoleWriteImage(Bitmap source)
{
    int sMax = 39;
    decimal percent = Math.Min(decimal.Divide(sMax, source.Width), decimal.Divide(sMax, source.Height));
    Size dSize = new Size((int)(source.Width * percent), (int)(source.Height * percent));   
    Bitmap bmpMax = new Bitmap(source, dSize.Width * 2, dSize.Height);
    for (int i = 0; i < dSize.Height; i++)
    {
        for (int j = 0; j < dSize.Width; j++)
        {
            ConsoleWritePixel(bmpMax.GetPixel(j * 2, i));
            ConsoleWritePixel(bmpMax.GetPixel(j * 2 + 1, i));
        }
        System.Console.WriteLine();
    }
    Console.ResetColor();
}

Verwendung:

Bitmap bmpSrc = new Bitmap(@"HuwnC.gif", true);    
ConsoleWriteImage(bmpSrc);

BEARBEITEN

Farbabstand ist ein komplexes Thema (Hier, Hier und Links auf diesen Seiten ...). Ich habe versucht, die Entfernung in YUV zu berechnen, und die Ergebnisse waren eher schlechter als in RGB. Sie könnten besser mit Lab und DeltaE sein, aber das habe ich nicht versucht. Die Entfernung in RGB scheint gut genug zu sein. In der Tat sind die Ergebnisse sowohl für euklidische als auch für Manhattan-Distanzen im RGB-Farbraum sehr ähnlich, daher vermute ich, dass es nur zu wenige Farben gibt, aus denen man wählen kann.

Der Rest ist nur Brute-Force-Vergleich der Farbe gegen alle Kombinationen von Farben und Mustern (= Symbole). Ich habe angegeben, dass das Füllverhältnis für ▒▓█ 1/4, 2/4, 3/4 und 4/4 sein soll. In diesem Fall ist das dritte Symbol tatsächlich redundant zu dem ersten. Aber wenn die Verhältnisse nicht so einheitlich sind (abhängig von der Schrift), könnten sich die Ergebnisse ändern, also habe ich es für zukünftige Verbesserungen dort gelassen. Die durchschnittliche Farbe des Symbols wird als gewogener Durchschnitt von foregroudColor und backgroundColor nach Füllgrad berechnet. Es nimmt lineare Farben an, was auch eine große Vereinfachung ist. Es gibt also noch Raum für Verbesserungen.


49
2017-11-15 00:44



Obwohl das Anzeigen eines Bilds in einer Konsole nicht die beabsichtigte Verwendung der Konsole ist, können Sie die Dinge sicherlich hacken, da das Konsolenfenster wie jedes andere Fenster nur ein Fenster ist.

Eigentlich habe ich angefangen, eine Textsteuerungsbibliothek für Konsolenanwendungen mit Grafikunterstützung zu entwickeln. Ich habe das nie beendet, obwohl ich eine funktionierende Proof-of-Concept-Demo habe:

Text controls with image

Und wenn Sie die Konsolenschriftgröße erhalten, können Sie das Bild sehr genau platzieren.

So können Sie es machen:

static void Main(string[] args)
{
    Console.WriteLine("Graphics in console window!");

    Point location = new Point(10, 10);
    Size imageSize = new Size(20, 10); // desired image size in characters

    // draw some placeholders
    Console.SetCursorPosition(location.X - 1, location.Y);
    Console.Write(">");
    Console.SetCursorPosition(location.X + imageSize.Width, location.Y);
    Console.Write("<");
    Console.SetCursorPosition(location.X - 1, location.Y + imageSize.Height - 1);
    Console.Write(">");
    Console.SetCursorPosition(location.X + imageSize.Width, location.Y + imageSize.Height - 1);
    Console.WriteLine("<");

    string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonPictures), @"Sample Pictures\tulips.jpg");
    using (Graphics g = Graphics.FromHwnd(GetConsoleWindow()))
    {
        using (Image image = Image.FromFile(path))
        {
            Size fontSize = GetConsoleFontSize();

            // translating the character positions to pixels
            Rectangle imageRect = new Rectangle(
                location.X * fontSize.Width,
                location.Y * fontSize.Height,
                imageSize.Width * fontSize.Width,
                imageSize.Height * fontSize.Height);
            g.DrawImage(image, imageRect);
        }
    }
}

So erhalten Sie die aktuelle Konsolenschriftgröße:

private static Size GetConsoleFontSize()
{
    // getting the console out buffer handle
    IntPtr outHandle = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, 
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        IntPtr.Zero,
        OPEN_EXISTING,
        0,
        IntPtr.Zero);
    int errorCode = Marshal.GetLastWin32Error();
    if (outHandle.ToInt32() == INVALID_HANDLE_VALUE)
    {
        throw new IOException("Unable to open CONOUT$", errorCode);
    }

    ConsoleFontInfo cfi = new ConsoleFontInfo();
    if (!GetCurrentConsoleFont(outHandle, false, cfi))
    {
        throw new InvalidOperationException("Unable to get font information.");
    }

    return new Size(cfi.dwFontSize.X, cfi.dwFontSize.Y);            
}

Und die erforderlichen zusätzlichen WinApi Aufrufe, Konstanten und Typen:

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetConsoleWindow();

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(
    string lpFileName,
    int dwDesiredAccess,
    int dwShareMode,
    IntPtr lpSecurityAttributes,
    int dwCreationDisposition,
    int dwFlagsAndAttributes,
    IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetCurrentConsoleFont(
    IntPtr hConsoleOutput,
    bool bMaximumWindow,
    [Out][MarshalAs(UnmanagedType.LPStruct)]ConsoleFontInfo lpConsoleCurrentFont);

[StructLayout(LayoutKind.Sequential)]
internal class ConsoleFontInfo
{
    internal int nFont;
    internal Coord dwFontSize;
}

[StructLayout(LayoutKind.Explicit)]
internal struct Coord
{
    [FieldOffset(0)]
    internal short X;
    [FieldOffset(2)]
    internal short Y;
}

private const int GENERIC_READ = unchecked((int)0x80000000);
private const int GENERIC_WRITE = 0x40000000;
private const int FILE_SHARE_READ = 1;
private const int FILE_SHARE_WRITE = 2;
private const int INVALID_HANDLE_VALUE = -1;
private const int OPEN_EXISTING = 3;

Und das Ergebnis:

[Graphics in Console


79
2017-11-11 14:22



Wenn Sie zweimal ASCII 219 (█) verwenden, haben Sie so etwas wie ein Pixel (██). Jetzt sind Sie durch die Anzahl der Pixel und die Anzahl der Farben in Ihrer Konsolenanwendung eingeschränkt.

  • Wenn Sie die Standardeinstellungen beibehalten, haben Sie etwa 39x39 Pixel, wenn Sie mehr möchten, können Sie die Größe der Konsole ändern Console.WindowHeight = resSize.Height + 1;und Console.WindowWidth = resultSize.Width * 2;

  • Sie müssen das Seitenverhältnis des Bildes so weit wie möglich beibehalten, so dass Sie in den meisten Fällen keine 39x39 haben

  • Malwyn hat eine völlig unterschätzte Methode zum Konvertieren gepostet System.Drawing.Color zu System.ConsoleColor

so würde mein Ansatz sein

using System.Drawing;

public static void ConsoleWriteImage(Bitmap bmpSrc)
{
    int sMax = 39;
    decimal percent = Math.Min(decimal.Divide(sMax, bmpSrc.Width), decimal.Divide(sMax, bmpSrc.Height));
    Size resSize = new Size((int)(bmpSrc.Width * percent), (int)(bmpSrc.Height * percent));
    Func<System.Drawing.Color, int> ToConsoleColor = c =>
    {
        int index = (c.R > 128 | c.G > 128 | c.B > 128) ? 8 : 0; 
        index |= (c.R > 64) ? 4 : 0;
        index |= (c.G > 64) ? 2 : 0;
        index |= (c.B > 64) ? 1 : 0; 
        return index;
    };
    Bitmap bmpMin = new Bitmap(bmpSrc, resSize);
    for (int i = 0; i < resSize.Height; i++)
    {
        for (int j = 0; j < resSize.Width; j++)
        {
            Console.ForegroundColor = (ConsoleColor)ToConsoleColor(bmpMin.GetPixel(j, i));
            Console.Write("██");
        }
        System.Console.WriteLine();
    }
}

also kannst du

ConsoleWriteImage(new Bitmap(@"C:\image.gif"));

Beispiel Eingabe:

enter image description here

Beispielausgabe:

enter image description here


53
2017-11-09 07:46



das hat Spaß gemacht. Vielen Dank fuboIch habe deine Lösung ausprobiert und konnte die Auflösung der Vorschau um 4 erhöhen (2x2).

Ich habe festgestellt, dass Sie die Hintergrundfarbe für jedes einzelne Zeichen festlegen können. Anstatt also zwei ASCII 219 (█) -Zeichen zu verwenden, habe ich zweimal ASCII 223 (▀) mit unterschiedlichen Vordergrund- und Hintergrundfarben verwendet. Dies teilt das große Pixel (██) in 4 Subpixel wie dieses (▀▄).

In diesem Beispiel lege ich beide Bilder nebeneinander, so dass Sie den Unterschied leicht sehen können:

enter image description here

Hier ist der Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ConsoleWithImage
{
  class Program
  {

    public static void ConsoleWriteImage(Bitmap bmpSrc)
    {
        int sMax = 39;
        decimal percent = Math.Min(decimal.Divide(sMax, bmpSrc.Width), decimal.Divide(sMax, bmpSrc.Height));
        Size resSize = new Size((int)(bmpSrc.Width * percent), (int)(bmpSrc.Height * percent));
        Func<System.Drawing.Color, int> ToConsoleColor = c =>
        {
            int index = (c.R > 128 | c.G > 128 | c.B > 128) ? 8 : 0;
            index |= (c.R > 64) ? 4 : 0;
            index |= (c.G > 64) ? 2 : 0;
            index |= (c.B > 64) ? 1 : 0;
            return index;
        };
        Bitmap bmpMin = new Bitmap(bmpSrc, resSize.Width, resSize.Height);
        Bitmap bmpMax = new Bitmap(bmpSrc, resSize.Width * 2, resSize.Height * 2);
        for (int i = 0; i < resSize.Height; i++)
        {
            for (int j = 0; j < resSize.Width; j++)
            {
                Console.ForegroundColor = (ConsoleColor)ToConsoleColor(bmpMin.GetPixel(j, i));
                Console.Write("██");
            }

            Console.BackgroundColor = ConsoleColor.Black;
            Console.Write("    ");

            for (int j = 0; j < resSize.Width; j++)
            {
                Console.ForegroundColor = (ConsoleColor)ToConsoleColor(bmpMax.GetPixel(j * 2, i * 2));
                Console.BackgroundColor = (ConsoleColor)ToConsoleColor(bmpMax.GetPixel(j * 2, i * 2 + 1));
                Console.Write("▀");

                Console.ForegroundColor = (ConsoleColor)ToConsoleColor(bmpMax.GetPixel(j * 2 + 1, i * 2));
                Console.BackgroundColor = (ConsoleColor)ToConsoleColor(bmpMax.GetPixel(j * 2 + 1, i * 2 + 1));
                Console.Write("▀");
            }
            System.Console.WriteLine();
        }
    }

    static void Main(string[] args)
    {
        System.Console.WindowWidth = 170;
        System.Console.WindowHeight = 40;

        Bitmap bmpSrc = new Bitmap(@"image.bmp", true);

        ConsoleWriteImage(bmpSrc);

        System.Console.ReadLine();
    }
  }
}

Um das Beispiel auszuführen, muss sich die Bitmap "image.bmp" im selben Verzeichnis wie die ausführbare Datei befinden. Ich habe die Größe der Konsole erhöht, die Größe der Vorschau ist noch 39 und kann bei geändert werden int sMax = 39;.

Die Lösung von Taffer ist auch sehr cool. Sie haben zwei meine Upvote ...


35
2017-11-13 09:06



Ich habe gelesen Farbräume und LABOR Platz scheint eine gute Option für Sie zu sein (siehe diese Fragen: Eine genaue "Entfernung" zwischen Farben finden und Algorithmus zur Überprüfung der Ähnlichkeit von Farben)

Zitat von Wikipedia CIELAB Seite, die Vorteile dieses Farbraums sind:

Im Gegensatz zu den RGB- und CMYK-Farbmodellen ist die Lab-Farbe so ausgelegt, dass sie sich dem menschlichen Sehvermögen annähert. Es strebt nach Wahrnehmungsgleichförmigkeit, und seine L-Komponente entspricht der menschlichen Wahrnehmung von Leichtigkeit. Somit kann es verwendet werden, um genaue Farbbalancekorrekturen durchzuführen, indem Ausgangskurven in den a- und b-Komponenten modifiziert werden.

Um den Abstand zwischen Farben zu messen, die Sie verwenden können Delta E Entfernung.

Damit können Sie sich besser annähern Color zu ConsoleColor:

Erstens können Sie ein definieren CieLab Klasse, um Farben in diesem Raum darzustellen:

public class CieLab
{
    public double L { get; set; }
    public double A { get; set; }
    public double B { get; set; }

    public static double DeltaE(CieLab l1, CieLab l2)
    {
        return Math.Pow(l1.L - l2.L, 2) + Math.Pow(l1.A - l2.A, 2) + Math.Pow(l1.B - l2.B, 2);
    }

    public static CieLab Combine(CieLab l1, CieLab l2, double amount)
    {
        var l = l1.L * amount + l2.L * (1 - amount);
        var a = l1.A * amount + l2.A * (1 - amount);
        var b = l1.B * amount + l2.B * (1 - amount);

        return new CieLab { L = l, A = a, B = b };
    }
}

Es gibt zwei statische Methoden, eine zum Messen der Entfernung mit Delta E (DeltaE) und andere, um zwei Farben zu kombinieren, die angeben, wie viel von jeder Farbe (Combine).

Und für die Transformation von RGB zu LAB Sie können die folgende Methode verwenden (aus Hier):

public static CieLab RGBtoLab(int red, int green, int blue)
{
    var rLinear = red / 255.0;
    var gLinear = green / 255.0;
    var bLinear = blue / 255.0;

    double r = rLinear > 0.04045 ? Math.Pow((rLinear + 0.055) / (1 + 0.055), 2.2) : (rLinear / 12.92);
    double g = gLinear > 0.04045 ? Math.Pow((gLinear + 0.055) / (1 + 0.055), 2.2) : (gLinear / 12.92);
    double b = bLinear > 0.04045 ? Math.Pow((bLinear + 0.055) / (1 + 0.055), 2.2) : (bLinear / 12.92);

    var x = r * 0.4124 + g * 0.3576 + b * 0.1805;
    var y = r * 0.2126 + g * 0.7152 + b * 0.0722;
    var z = r * 0.0193 + g * 0.1192 + b * 0.9505;

    Func<double, double> Fxyz = t => ((t > 0.008856) ? Math.Pow(t, (1.0 / 3.0)) : (7.787 * t + 16.0 / 116.0));

    return new CieLab
    {
        L = 116.0 * Fxyz(y / 1.0) - 16,
        A = 500.0 * (Fxyz(x / 0.9505) - Fxyz(y / 1.0)),
        B = 200.0 * (Fxyz(y / 1.0) - Fxyz(z / 1.0890))
    };
}

Die Idee ist Schattenzeichen wie @AntoninLejsek tun ('█', '▓', '▒', '░'), dies ermöglicht es Ihnen, mehr als 16 Farben zu erhalten, die die Konsolenfarben kombinieren (mit Combine Methode).

Hier können wir einige Verbesserungen vornehmen, indem wir die zu verwendenden Farben vorberechnen:

class ConsolePixel
{
    public char Char { get; set; }

    public ConsoleColor Forecolor { get; set; }
    public ConsoleColor Backcolor { get; set; }
    public CieLab Lab { get; set; }
}

static List<ConsolePixel> pixels;
private static void ComputeColors()
{
    pixels = new List<ConsolePixel>();

    char[] chars = { '█', '▓', '▒', '░' };

    int[] rs = { 0, 0, 0, 0, 128, 128, 128, 192, 128, 0, 0, 0, 255, 255, 255, 255 };
    int[] gs = { 0, 0, 128, 128, 0, 0, 128, 192, 128, 0, 255, 255, 0, 0, 255, 255 };
    int[] bs = { 0, 128, 0, 128, 0, 128, 0, 192, 128, 255, 0, 255, 0, 255, 0, 255 };

    for (int i = 0; i < 16; i++)
        for (int j = i + 1; j < 16; j++)
        {
            var l1 = RGBtoLab(rs[i], gs[i], bs[i]);
            var l2 = RGBtoLab(rs[j], gs[j], bs[j]);

            for (int k = 0; k < 4; k++)
            {
                var l = CieLab.Combine(l1, l2, (4 - k) / 4.0);

                pixels.Add(new ConsolePixel
                {
                    Char = chars[k],
                    Forecolor = (ConsoleColor)i,
                    Backcolor = (ConsoleColor)j,
                    Lab = l
                });
            }
        }
}

Eine weitere Verbesserung könnte der direkte Zugriff auf die Bilddaten mit sein LockBits anstatt zu verwenden GetPixel.

AKTUALISIEREN: Wenn das Bild Teile mit der gleichen Farbe haben, können Sie erheblich beschleunigen das Prozesszeichnen Stück von Zeichen mit den gleichen Farben, anstelle von Personen chars:

public static void DrawImage(Bitmap source)
{
    int width = Console.WindowWidth - 1;
    int height = (int)(width * source.Height / 2.0 / source.Width);

    using (var bmp = new Bitmap(source, width, height))
    {
        var unit = GraphicsUnit.Pixel;
        using (var src = bmp.Clone(bmp.GetBounds(ref unit), PixelFormat.Format24bppRgb))
        {
            var bits = src.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, src.PixelFormat);
            byte[] data = new byte[bits.Stride * bits.Height];

            Marshal.Copy(bits.Scan0, data, 0, data.Length);

            for (int j = 0; j < height; j++)
            {
                StringBuilder builder = new StringBuilder();
                var fore = ConsoleColor.White;
                var back = ConsoleColor.Black;

                for (int i = 0; i < width; i++)
                {
                    int idx = j * bits.Stride + i * 3;
                    var pixel = DrawPixel(data[idx + 2], data[idx + 1], data[idx + 0]);


                    if (pixel.Forecolor != fore || pixel.Backcolor != back)
                    {
                        Console.ForegroundColor = fore;
                        Console.BackgroundColor = back;
                        Console.Write(builder);

                        builder.Clear();
                    }

                    fore = pixel.Forecolor;
                    back = pixel.Backcolor;
                    builder.Append(pixel.Char);
                }

                Console.ForegroundColor = fore;
                Console.BackgroundColor = back;
                Console.WriteLine(builder);
            }

            Console.ResetColor();
        }
    }
}

private static ConsolePixel DrawPixel(int r, int g, int b)
{
    var l = RGBtoLab(r, g, b);

    double diff = double.MaxValue;
    var pixel = pixels[0];

    foreach (var item in pixels)
    {
        var delta = CieLab.DeltaE(l, item.Lab);
        if (delta < diff)
        {
            diff = delta;
            pixel = item;
        }
    }

    return pixel;
}

Endlich, ruf an DrawImage so:

static void Main(string[] args)
{
    ComputeColors();

    Bitmap image = new Bitmap("image.jpg", true);
    DrawImage(image);

}

Ergebnis Bilder:

Console1

Console2



Die folgenden Lösungen basieren nicht auf Zeichen, sondern liefern vollständige detaillierte Bilder


Sie können über jedes Fenster mit seinem zeichnen Handler ein erstellen Graphics Objekt. Um den Handler einer Konsolenanwendung zu erhalten, können Sie ihn importieren GetConsoleWindow:

[DllImport("kernel32.dll", EntryPoint = "GetConsoleWindow", SetLastError = true)]
private static extern IntPtr GetConsoleHandle();

Erstellen Sie dann eine Grafik mit dem Handler (mit Graphics.FromHwnd) und zeichnen Sie das Bild mit den Methoden in GraphicsObjekt, zum Beispiel:

static void Main(string[] args)
{            
    var handler = GetConsoleHandle();

    using (var graphics = Graphics.FromHwnd(handler))
    using (var image = Image.FromFile("img101.png"))
        graphics.DrawImage(image, 50, 50, 250, 200);
}

Version 1

Das sieht gut aus, aber wenn die Größe der Konsole geändert oder gescrollt wird, verschwindet das Bild, weil die Fenster aktualisiert werden (möglicherweise ist es in Ihrem Fall möglich, einen Mechanismus zu implementieren, um das Bild neu zu zeichnen).


Eine andere Lösung ist das Einbetten eines Fensters (Form) in die Konsolenanwendung. Um dies zu tun, müssen Sie importieren SetParent (und MoveWindow um das Fenster in der Konsole zu verschieben):

[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

Dann müssen Sie nur ein erstellen Form und einstellen BackgroundImage Eigenschaft auf das gewünschte Bild (tun Sie es auf a Thread oder Task um zu vermeiden, die Konsole zu blockieren):

static void Main(string[] args)
{
    Task.Factory.StartNew(ShowImage);

    Console.ReadLine();
}

static void ShowImage()
{
    var form = new Form
    {                
        BackgroundImage = Image.FromFile("img101.png"),
        BackgroundImageLayout = ImageLayout.Stretch
    };

    var parent = GetConsoleHandle();
    var child = form.Handle;

    SetParent(child, parent);
    MoveWindow(child, 50, 50, 250, 200, true);

    Application.Run(form);
}

Version2

Natürlich können Sie einstellen FormBorderStyle = FormBorderStyle.None Fensterrahmen ausblenden (rechtes Bild)

In diesem Fall können Sie die Größe der Konsole ändern und das Bild / Fenster immer noch dort sein.

Ein Vorteil dieses Ansatzes besteht darin, dass Sie das Fenster an der gewünschten Stelle finden und das Bild jederzeit ändern können, indem Sie es einfach ändern BackgroundImage Eigentum.


19
2018-04-29 22:14



Es gibt keinen direkten Weg. Aber Sie können versuchen, einen Bild-zu-Ascii-Art-Konverter wie zu verwenden dieses


4
2017-11-05 07:10



Ja, Sie können es tun, wenn Sie die Frage etwas ausdehnen, indem Sie eine öffnen Form aus der Konsolenanwendung heraus.

So können Sie Ihre Konsolenanwendung ein Formular öffnen und ein Bild anzeigen lassen:

  • Fügen Sie diese zwei Referenzen in Ihr Projekt ein: System.Drawing und System.Windows.Forms
  • schließe auch die beiden Namespaces ein:

using System.Windows.Forms;
using System.Drawing;

Sehen diesen Beitrag, wie man das macht!

Jetzt brauchst du es nur, um etwas hinzuzufügen:

Form form1 = new Form();
form1.BackgroundImage = bmp;
form1.ShowDialog();

Natürlich können Sie auch ein PictureBox..

Und Sie können verwenden form1.Show(); um die Konsole am Leben zu halten, während die Vorschau zeigt ..

Ursprünglicher Beitrag: Natürlich können Sie ein Bild nicht richtig anzeigen Innerhalb ein 25x80 Fenster; Selbst wenn Sie ein größeres Fenster verwenden und Grafiken blockieren, wäre das keine Vorschau, sondern ein Chaos!

Aktualisieren: Sieht aus, als könntest du nach all dem GDI ein Bild auf das Konsolenformular zeichnen; sieh taffers Antwort!


1
2017-11-05 10:35