More ASCII Art
A few recent posts on the weblogs.asp.net feed [1 2 3] reminded me of a some code I wrote a year ago and have been meaning to post.
This is a simple ASP.NET page - you upload the image file and input the text; it scales the text to the same proportions as the image and applies the HTML color in a font tag. Most ASCII Art things just let you pick the image, this one lets you pick your text too - helpful if you want to embed your copyright into the image. Okay, yes, it is completely useless. One obvious optimization would be grouping to eliminate unnecessary font tags when adjacent characters are the same color (<font color='#BFBFBF'>i</font><font color='#BFBFBF'>t</font> becomes <font color='#BFBFBF'>it</font>).
Try it: [here]
Sample output:
With Microsoft® Visual Studio® .NET and the Microsoft .NET Framework, developers can develop Web
services quickly and integrate them easily with other applications. Most developers can leverage
existing skills, because the .NET Framework's common language runtime allows you to develop Web
services using any modern programming language.
* Microsoft Visual Studio .NET and the Microsoft
.NET Framework supply a complete solution for developers to build, deploy, and run Web services.
*
These tools help enhance the performance, reliability, and security of Web services.
Microsoft
Visual Studio .NET
Developers can use a variety of programming environments to create Web services.
Microsoft Visual Studio .NET represents the best development environment for .NET-connected software
and services.
Visual Studio .NET advances the high-productivity programming languages: Microsoft
Visual Basic®, which includes new object-oriented programming features; Microsoft Visual C++®, which
advances Microsoft Windows® development and enables you to build .NET-connected applications; and C#,
which brings RAD to the C and C++ developer.
Program in the Right Language for the Task
Visual
Studio .NET provides a single, unified development environment. Built on the .NET Framework, it
provides support for working with Web services created in all modern programming languages.
Applications and Web services created in one language can be programmed against and debugged in any
other language supported by Visual Studio .NET. This greatly enhances the ability to use existing Web
services to build new and exciting solutions.
Transform Applications into Web Services
Visual
Studio .NET automatically creates the necessary XML and SOAP interface needed to turn an application
into a Web service. Developers can concentrate on building the application, not on the plumbing for the
Web service.
Reuse Existing Web Services
Developing with Web services is similar to developing with
components. Visual Studio .NET gives developers the ease of importing Web services or using Web
services hosted remotely and programming against them as they would a COM element today, saving time
and giving developers the opportunity to concentrate on core functionality.
Microsoft .NET Framework
and Microsoft .NET Compact Framework
The .NET Framework, and the device-focused .NET Compact
Framework, are high-productivity, standards-based, multi-language application execution environments
that handle essential plumbing chores and ease deployment. The application execution environment
manages memory, addresses versioning issues, and improves the reliability, scalability, and security of
your application. Components include the common language runtime, a rich set of class libraries for
building Web services, and Microsoft ASP.NET.
The common language runtime is the engine in the .NET
Framework that provides a managed execution environment, which is protected by industry-standard
technologies, and is designed to support developers using many different languages to create
applications.
Code:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;
namespace AsciiArt
{
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox txtOutput;
protected System.Web.UI.WebControls.Button btnGo;
protected System.Web.UI.HtmlControls.HtmlInputFile file;
protected System.Web.UI.WebControls.TextBox txtInput;
private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
StringBuilder input = new StringBuilder();
for (int i = 0; i < 2500; i++)
{
input.Append("blah ");
}
txtInput.Text = input.ToString();
}
}
private string ColorizeText(System.Drawing.Image image, string input)
{
//determine how to scale the text
int textLength = input.Length;
int imageHeight = image.Height;
int imageWidth = image.Width;
double ratio = (double)imageHeight / (double)imageWidth;
StringBuilder output = new StringBuilder();
//letters are about twice as tall as wide; correct
ratio /= 2;
//height * width = text
//height / width = ratio
//width = text / height
//width = height / ratio
//height / ratio = length / height
//height^2 = ratio * text
//height = sqrt (ratio * text)
int rows = (int)(Math.Sqrt(ratio * textLength));
int columns = (int)(textLength / rows);
//Chop the text into rows, since the word breaks will cause this to be a little
//uneven so the exact row count is variable.
string inputBuffer = input;
ArrayList rowText = new ArrayList();
int startPointer = 0;
int endPointer = columns;
do
{
endPointer = input.LastIndexOf(" ",(startPointer + columns));
rowText.Add(input.Substring(startPointer,endPointer-startPointer));
startPointer = endPointer + 1;
}
while (startPointer+columns<=input.Length);
if (startPointer<input.Length)
rowText.Add(input.Substring(startPointer));
using (Bitmap bitmap = new Bitmap(image,columns,rowText.Count))
{
output.Append("<span style='font-family: Lucinda Console,Courier New;font-size: 8px;'>");
int rowCtr = 0;
int colCtr = 0;
//Iterate the rows
foreach (string row in rowText)
{
colCtr = 0;
//Iterate each character in the row
foreach (char letter in row.ToCharArray())
{
if (letter == ' ')
{
output.Append(" ");
}
else
{
Color color = bitmap.GetPixel(colCtr,rowCtr);
//If the pizel is white, darken it up a bit.
if (color.GetBrightness() > .8)
output.AppendFormat("<font color='#{0:X2}{1:X2}{2:X2}'>{3}</font>", (int)(.75*color.R), (int)(.75*color.G), (int)(.75*color.B), letter);
else
output.AppendFormat("<font color='#{0:X2}{1:X2}{2:X2}'>{3}</font>", color.R, color.G, color.B, letter);
}
colCtr++;
}
output.Append("<br>");
rowCtr++;
}
}
output.Append("</span>");
return output.ToString();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnGo.Click += new System.EventHandler(this.btnGo_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void btnGo_Click(object sender, System.EventArgs e)
{
try
{
using (System.Drawing.Image image = System.Drawing.Image.FromStream(file.PostedFile.InputStream))
{
string colorizedText = ColorizeText(image, txtInput.Text);
Response.Write(colorizedText);
txtOutput.Text = colorizedText;
}
}
catch (Exception ex)
{
}
}
}
}
<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" validateRequest="false" Inherits="AsciiArt.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>colorizer.r.r.</title>
<style>
body {
font: Tahoma, Arial, sans-serif;
margin : 15px 0px 0px 15px;
background : #f3f4fb;
}
</style>
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<h3>A slightly different take on the ASCII Art thing. This takes your block of ascii text and colorizes it to match the colors in the image you upload. Makes more sense when you see it in action - give it a try:</h3>
<FIELDSET>
<LEGEND>1. Upload source image</LEGEND>
<INPUT type="file" runat="server" id="file">
</FIELDSET>
<br>
<FIELDSET>
<LEGEND>2. Enter text to be colorized</LEGEND>
<asp:TextBox id="txtInput" runat="server" Rows="10" Columns="60" TextMode="MultiLine"></asp:TextBox>
</FIELDSET>
<br>
<FIELDSET>
<LEGEND>3. Delight in your glorious new HTML</LEGEND>
<asp:TextBox id="txtOutput" runat="server" Rows="10" Columns="60" TextMode="MultiLine"></asp:TextBox></P>
</FIELDSET>
<asp:Button id="btnGo" runat="server" Text="Go"></asp:Button></P>
</form>
</body>
</HTML>