Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Omer van Kloeten's Facebook profile

Get Firefox

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

Old Skool Trippin', Part I

I never was a good ANSI artist, even when I tried, back in the mid-90's. All I got when I loaded ACiDDraw was pretty fair results, but nothing great. However, I still have a warm spot deep inside for old skool ansi and ascii art. (Being a member of iCE kind of helps, too ;)

One of the signatures I made for my emails was a hand made colored ascii version of The Project's logo (since people started to complain about my sending an image with every new email). It made me long for the good old days, so I went and made a little program that takes an image and creates a colored ascii representation of it using the '$' (dollar) sign in HTML. Came out rather nice, but I couldn't make out the css line-height to font-size ratios. Oh, well.

So here it is, but first, an example so you understand what I'm talking about:
I made a couple of examples for the first image I found:

So here's a converted image with a factor of 1, of 3 and of 5.

Here's the code (click on the region to collapse):

#region The Code
using System;
using System.Text;
using System.IO;
using System.Drawing;

namespace AnsiStuff
{
    class ColoredAsciiMaker
    {
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length == 2)
            {
                // The factor is the size of the original image in comparison to the size of the output
                // image. 1 is for best quality and largest file size. more for lesser quality.
                int factor = Convert.ToInt32(args[1]);
                Image img = Image.FromFile(args[0]);

                using (StreamWriter sw = File.CreateText(args[0] + ".htm"))
                {
                    if (img is Bitmap)
                    {
                        // Create a thumbnail accoding to the factor.
                        using (Bitmap bmp = ((Bitmap)(img)).GetThumbnailImage(img.Width / factor,
                                   img.Height / factor,
                                   new System.Drawing.Image.GetThumbnailImageAbort(new ColoredAsciiMaker().kek),
                                   IntPtr.Zero) as Bitmap)
                        {
                            StringBuilder sb = new StringBuilder();
                            Color oldColor = Color.Empty;

                            for (int y = 0; y < bmp.Height; y++)
                            {
                                for (int x = 0; x < bmp.Width; x++)
                                {
                                    Color color = bmp.GetPixel(x, y);

                                    // The old color is saved so we don't repeat a font tag twice
                                    // for consecutive same color pixels.
                                    if (oldColor != color)
                                    {
                                        // If the previous color was white, there's no reason to
                                        // close a font tag.
                                        if (!((oldColor.R == Color.White.R) && (oldColor.G == Color.White.G) && (oldColor.B == Color.White.B)))
                                        {
                                            sb.Append("</font>");
                                        }

                                        // If the current color is not white, create a font tag.
                                        if (!(color.R == Color.White.R && color.G == Color.White.G && color.B == Color.White.B))
                                        {
                                            sb.Append("<font color=\"#" +
                                                (color.R < 16 ? "0" + color.R.ToString("X") : color.R.ToString("X")) + 
                                                (color.G < 16 ? "0" + color.G.ToString("X") : color.G.ToString("X")) + 
                                                (color.B < 16 ? "0" + color.B.ToString("X") : color.B.ToString("X")) + 
                                                "\">");
                                        }

                                        oldColor = color;
                                    }

                                    if (!(color.R == Color.White.R && color.G == Color.White.G && color.B == Color.White.B))
                                    {
                                        sb.Append('$');
                                    }
                                    else
                                    {
                                        // When the color is white, to save space,
                                        // we just place a whitespace.
                                        sb.Append(' ');
                                    }
                                }

                                sb.Append(Environment.NewLine);
                            }

                            string output = sb.ToString();

                            // Clear the last font tag.
                            if (output.StartsWith("</font>")) output = output.Substring("</font>".Length);

                            sw.Write("<pre style=\"font-size: " + factor + "px; letter-spacing: 0mm; line-height: " + (factor + 1) / 2 + "px; font-weight: bold\">" + output + "</pre>");
                        }
                    }
                }
            }
        }

        public bool kek()
        {
            return true;
        }
    }
}
#endregion

One final note: The GetThumbnailImage method has a couple of rather foolish parameters. One's said to be for future use and the other should always be IntPtr.Zero. What's this supposed to mean?

To be continued...

Comments

TrackBack said:

# July 30, 2004 5:57 PM

TrackBack said:

# July 30, 2004 6:13 PM

TrackBack said:

# July 30, 2004 6:15 PM

TrackBack said:

# July 31, 2004 5:41 PM

TrackBack said:

# August 1, 2004 5:35 PM

Noah Coad's Code said:

When I see a blog post or article that I want to read, investigate, follow up on, etc, I jot it down...
# August 16, 2006 3:17 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)