2010-04-27 26 views
14

Tôi muốn nó hiển thị hình ảnh động không nhấp nháy như lệnh Linux tuyệt vời này; slCách tạo hoạt ảnh ASCII trong ứng dụng Windows Console bằng C#?

http://www.youtube.com/watch?v=9GyMZKWjcYU

tôi sẽ đánh giá cao một nhỏ & dụ ngu ngốc của tiếng nói ... một con ruồi.

Cảm ơn!

+0

Chỉ cần cập nhật câu trả lời của tôi. Hãy vui vẻ :) –

+0

Hmm, đó là định nghĩa của nhấp nháy, không phải là một "pixel" duy nhất là giống nhau từ một khung hình để tiếp theo. Di chuyển nhanh. –

Trả lời

21

Chỉ cần sử dụng Console.SetCursorPosition để di chuyển con trỏ đến một vị trí nhất định, sau đó Console.Write một ký tự. Trước mỗi khung hình, bạn phải xóa khung trước bằng cách ghi đè lên nó bằng dấu cách. Heres một ví dụ nhỏ tôi chỉ xây dựng:

class Program 
{ 
    static void Main(string[] args) 
    { 
     char[] chars = new char[] { '.', '-', '+', '^', '°', '*' }; 
     for (int i = 0; ; i++) 
     { 
      if (i != 0) 
      { 
       // Delete the previous char by setting it to a space 
       Console.SetCursorPosition(6 - (i-1) % 6 - 1, Console.CursorTop); 
       Console.Write(" "); 
      } 

      // Write the new char 
      Console.SetCursorPosition(6 - i % 6 - 1, Console.CursorTop); 
      Console.Write(chars[i % 6]); 

      System.Threading.Thread.Sleep(100); 
     } 
    } 
} 

Bạn có thể ví dụ có một gif động, trích xuất tất cả các khung đơn/hình ảnh từ nó (xem làm thế nào để làm điều đó here), áp dụng một chuyển đổi ASCII (làm thế nào để làm điều đó được mô tả là here chẳng hạn) và in các khung này theo khung như trong ví dụ mã trên.

Cập nhật

Just for fun, tôi thực hiện những gì tôi vừa mô tả. Chỉ cần thử thay thế @"C:\some_animated_gif.gif" bằng đường dẫn đến một số gif động (không lớn). Ví dụ: lấy một bộ nạp AJAX gif từ here.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Image image = Image.FromFile(@"C:\some_animated_gif.gif"); 
     FrameDimension dimension = new FrameDimension(
          image.FrameDimensionsList[0]); 
     int frameCount = image.GetFrameCount(dimension); 
     StringBuilder sb; 

     // Remember cursor position 
     int left = Console.WindowLeft, top = Console.WindowTop; 

     char[] chars = { '#', '#', '@', '%', '=', '+', 
         '*', ':', '-', '.', ' ' }; 
     for (int i = 0; ; i = (i + 1) % frameCount) 
     { 
      sb = new StringBuilder(); 
      image.SelectActiveFrame(dimension, i); 

      for (int h = 0; h < image.Height; h++) 
      { 
       for (int w = 0; w < image.Width; w++) 
       { 
        Color cl = ((Bitmap)image).GetPixel(w, h); 
        int gray = (cl.R + cl.G + cl.B)/3; 
        int index = (gray * (chars.Length - 1))/255; 

        sb.Append(chars[index]); 
       } 
       sb.Append('\n'); 
      } 

      Console.SetCursorPosition(left, top); 
      Console.Write(sb.ToString()); 

      System.Threading.Thread.Sleep(100); 
     } 
    } 
} 
+1

Hãy tưởng tượng nếu chúng ta chỉ có một cửa sổ cmd backbuffered = D –

+0

@JonasB - bạn có ý nghĩa gì khi bị backbuffered? –

+0

Ồ, điều này thật tuyệt! Tôi dự định sử dụng nó (trong chế độ gỡ lỗi của khóa học). –

11

Just for fun:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading; 

class Program 
{ 
    static void ConsoleDraw(IEnumerable<string> lines, int x, int y) 
    { 
     if (x > Console.WindowWidth) return; 
     if (y > Console.WindowHeight) return; 

     var trimLeft = x < 0 ? -x : 0; 
     int index = y; 

     x = x < 0 ? 0 : x; 
     y = y < 0 ? 0 : y; 

     var linesToPrint = 
      from line in lines 
      let currentIndex = index++ 
      where currentIndex > 0 && currentIndex < Console.WindowHeight 
      select new { 
       Text = new String(line.Skip(trimLeft).Take(Math.Min(Console.WindowWidth - x, line.Length - trimLeft)).ToArray()), 
       X = x, 
       Y = y++ 
      }; 

     Console.Clear(); 
     foreach (var line in linesToPrint) 
     { 
      Console.SetCursorPosition(line.X, line.Y); 
      Console.Write(line.Text); 
     } 
    } 

    static void Main(string[] args) 
    { 
     Console.CursorVisible = false; 

     var arr = new[] 
     { 
      @"  ________________. ___  .______ ", 
      @"  /    |/ \ | _ \", 
      @"  | (-----| |----`/^\ | |_) |", 
      @"  \ \ | | //_\ \ |  /", 
      @" .-----) | | | /_____ \ | |\ \-------.", 
      @" |________/ |__| /__/  \__\| _| `.________|", 
      @" ____ __ ____ ___  .______ ________.", 
      @" \ \/\/// \ | _ \/  |", 
      @" \ \/ \/ //^\ | |_) || (-----`", 
      @"  \   // /_\ \ | /\ \", 
      @"  \ /\ // _____ \ | |\ \---) |", 
      @"  \__/ \__/ /__/  \__\|__| `._______/", 
     }; 

     var maxLength = arr.Aggregate(0, (max, line) => Math.Max(max, line.Length)); 
     var x = Console.BufferWidth/2 - maxLength/2; 
     for (int y = -arr.Length; y < Console.WindowHeight + arr.Length; y++) 
     { 
      ConsoleDraw(arr, x, y); 
      Thread.Sleep(100); 
     } 
    } 
} 
+2

Đây là một chủ đề thú vị ... Tôi thích nó. –

Các vấn đề liên quan