Created
January 28, 2015 09:38
-
-
Save davidwhitney/9fa81da34a6c7071246c to your computer and use it in GitHub Desktop.
ASCII Transcoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Drawing; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Text; | |
| using NUnit.Framework; | |
| namespace RubberDucky | |
| { | |
| [TestFixture] | |
| public class SomeTests | |
| { | |
| [Test] | |
| public void DuckYou() | |
| { | |
| var duck = (Bitmap)Bitmap.FromFile("skydiving-insurance.jpg"); | |
| var ascii = ImageTranscoder.Render(duck); | |
| System.Diagnostics.Debug.Write(ascii); | |
| } | |
| [TestCase] | |
| public void Render_GivenSingleBlackPixel_ReturnsBlock() | |
| { | |
| var pixel = CreateBitmapForMatrix(new[,] | |
| { | |
| {Color.Black} | |
| }); | |
| var output = ImageTranscoder.Render(pixel); | |
| Assert.That(output, Is.EqualTo("█")); | |
| } | |
| [Test] | |
| public void Render_GivenSingleWhitePixel_ReturnsSpace() | |
| { | |
| var pixel = CreateBitmapForMatrix(new[,] | |
| { | |
| {Color.White} | |
| }); | |
| var output = ImageTranscoder.Render(pixel); | |
| Assert.That(output, Is.EqualTo(" ")); | |
| } | |
| [Test] | |
| public void Render_GivenSingleYellowPixel_ReturnsSpace() | |
| { | |
| var pixel = CreateBitmapForMatrix(new[,] | |
| { | |
| {Color.Yellow} | |
| }); | |
| var output = ImageTranscoder.Render(pixel); | |
| Assert.That(output, Is.EqualTo("o")); | |
| } | |
| [Test] | |
| public void Render_GivenSingleRedPixel_Returns25pcGreyThing() | |
| { | |
| var pixel = CreateBitmapForMatrix(new[,] | |
| { | |
| {Color.DarkRed} | |
| }); | |
| var output = ImageTranscoder.Render(pixel); | |
| Assert.That(output, Is.EqualTo("▒")); | |
| } | |
| [Test] | |
| public void Render_GivenTwoPixelsOneBlackOneWhite_ReturnsBlockAndSpace() | |
| { | |
| var image = CreateBitmapForMatrix(new[,] | |
| { | |
| {Color.Black}, | |
| {Color.White} | |
| }); | |
| var output = ImageTranscoder.Render(image); | |
| Assert.That(output, Is.EqualTo("█ ")); | |
| } | |
| [Test] | |
| public void Render_GivenTwoByTwoImageCheckered_ReturnsWBBW() | |
| { | |
| var image = CreateBitmapForMatrix(new[,] | |
| { | |
| {Color.White, Color.Black}, | |
| {Color.Black, Color.White} | |
| }); | |
| var output = ImageTranscoder.Render(image); | |
| Assert.That(output, Is.EqualTo(" █\r\n█ ")); | |
| } | |
| private static Bitmap CreateBitmapForMatrix(Color[,] matrix) | |
| { | |
| var width = matrix.GetUpperBound(0); | |
| var height = matrix.GetUpperBound(1); | |
| var bitmap = new Bitmap(width + 1, height + 1); | |
| for (int y = 0; y <= height; y++) | |
| { | |
| for (int x = 0; x <= width; x++) | |
| { | |
| bitmap.SetPixel(x, y, matrix[x, y]); | |
| } | |
| } | |
| return bitmap; | |
| } | |
| } | |
| public class ImageTranscoder | |
| { | |
| private static readonly Dictionary<float, string> Map; | |
| static ImageTranscoder() | |
| { | |
| Map = new Dictionary<float, string> | |
| { | |
| {1, " "}, | |
| {0.75f, "."}, | |
| {0.5f, "o"}, | |
| {0.25f, "▒"}, | |
| {0, "█"} | |
| }; | |
| } | |
| public static string Render(Bitmap image) | |
| { | |
| image = ResizeAllSmallLike(image); | |
| var map = Map.OrderBy(kvp => kvp.Key); | |
| var sb = new StringBuilder(); | |
| for (int y = 0; y < image.Height; y++) | |
| { | |
| for (int x = 0; x < image.Width; x++) | |
| { | |
| var pixel = image.GetPixel(x, y); | |
| var currentChar = MapColourToCharacter(map, pixel); | |
| sb.Append(currentChar); | |
| } | |
| sb.Append(Environment.NewLine); | |
| } | |
| return PostProcessOutput(sb); | |
| } | |
| private static Bitmap ResizeAllSmallLike(Bitmap image) | |
| { | |
| if (image.Width <= 100 || image.Height <= 100) | |
| { | |
| return image; | |
| } | |
| Bitmap newImage = new Bitmap(100, 100); | |
| using (Graphics gr = Graphics.FromImage(newImage)) | |
| { | |
| gr.DrawImage(image, new Rectangle(0, 0, 100, 100)); | |
| } | |
| return newImage; | |
| } | |
| private static string MapColourToCharacter(IEnumerable<KeyValuePair<float, string>> map, Color pixel) | |
| { | |
| var brightness = pixel.GetBrightness(); | |
| var currentChar = ""; | |
| foreach (var kvp in map) | |
| { | |
| if (kvp.Key <= brightness) | |
| { | |
| currentChar = kvp.Value; | |
| } | |
| } | |
| return currentChar; | |
| } | |
| private static string PostProcessOutput(StringBuilder sb) | |
| { | |
| var output = sb.ToString(); | |
| output = output.Substring(0, output.Length - Environment.NewLine.Length); | |
| return output; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment