用C#开发程序进行ASCII艺术制作
我一直很喜欢 ASCII 艺术,而我对制作 ASCII 艺术的热情促使我探索 .NET 框架中的 GDI+。在本文中,
我将向您展示如何通过三个简单的步骤从 JPEG/Bitmap 图像生成 ASCII 艺术。
1、加载并调整图像大小。
2、读取每个像素,获取其颜色并将其转换为等效的灰度。
3、根据计算的灰度值为每个像素分配适当的字符。
让我们开始编写代码
首先使用图像路径初始化 System.Drawing.Bitmap 类。此类用于处理由像素数据定义的图像。
将图像调整为较低的分辨率,同时保持其纵横比。此步骤至关重要,因为图像的每个像素都代表
最终 ASCII 输出中的一个字符。例如,如果您要转换的 JPEG 图像的分辨率为 2592x1944,
则生成的文本将有 1944 行,每行 2592 个字符,您肯定不希望文本那么大。接下来,
定义 ASCII 图像的宽度,并通过按比例缩小来确定高度。
scalingFactor = asciiWidth / imageWidth
asciiHeight = imageHeight * scalingFactor
private void btnConvertToAscii_Click(object sender, EventArgs e)
{
btnConvertToAscii.Enabled = false;
//Load the Image from the specified path
Bitmap image = new Bitmap(txtPath.Text, true);
//Resize the image...
//I've used a trackBar to emulate Zoom In / Zoom Out feature
//This value sets the WIDTH, number of characters, of the text image
image = GetReSizedImage(image,this.trackBar.Value);
//Convert the resized image into ASCII
_Content = ConvertToAscii(image);
//Enclose the final string between <pre> tags to preserve its formatting
//and load it in the browser control
browserMain.DocumentText = "<pre>" + _Content + "</pre>";
btnConvertToAscii.Enabled = true;
}
通过指定新的宽度和高度初始化位图图像对象。从新图像对象创建图形对象。
将与图形对象关联的插值模式设置为 HighQualityBicubic。此模式可生成最高质量的转换图像(请参阅MSDN)。
您还可以尝试在代码中将插值模式更改为 HighQualityBilinear 或 NearestNeighbor,然后检查输出。
private Bitmap GetReSizedImage(Bitmap inputBitmap, int asciiWidth )
{
int asciiHeight=0;
//Calculate the new Height of the image from its width
asciiHeight = (int)Math.Ceiling((double)inputBitmap.Height * asciiWidth / inputBitmap.Width);
//Create a new Bitmap and define its resolution
Bitmap result = new Bitmap(asciiWidth, asciiHeight);
Graphics g = Graphics.FromImage((Image)result);
//The interpolation mode produces high quality images
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(inputBitmap, 0, 0, asciiWidth, asciiHeight);
g.Dispose();
return result;
}
ConvertToAscii() 方法接受调整大小的图像作为其输入,执行实际的转换过程。
从位图对象读取每个像素,规范其颜色以找到等效灰度,并根据其灰度因子分配字符。
这也可以实现为图像的亮度。颜色的红色、蓝色和绿色成分的平均值给出其灰度因子。
黑色的 (R, G, B) 值为 (0, 0, 0),白色为 (255,255,255),而银色为 (192,192,192)。
private string ConvertToAscii(Bitmap image)
{
Boolean toggle = false;
StringBuilder sb = new StringBuilder();
for (int h = 0; h < image.Height; h++)
{
for (int w = 0; w < image.Width; w++)
{
Color pixelColor = image.GetPixel(w, h);
//Average out the RGB components to find the Gray Color
int red = (pixelColor.R + pixelColor.G + pixelColor.B) / 3;
int green = (pixelColor.R + pixelColor.G + pixelColor.B) / 3;
int blue = (pixelColor.R + pixelColor.G + pixelColor.B) / 3;
Color grayColor = Color.FromArgb(red,green,blue);
//Use the toggle flag to minimize height-wise stretch
if (!toggle)
{
int index = (grayColor.R * 10) / 255;
sb.Append(_AsciiChars[index]);
}
}
if (!toggle)
{
sb.Append("<BR>");
toggle = true;
}
else
{
toggle = false;
}
}
return sb.ToString();
}
字符数组包含预先确定的 ASCII 字符列表,该列表根据字符的亮度和重量进行排序。
private string[] _AsciiChars = { "#", "#", "@", "%", "=", "+", "*", ":", "-", ".", " " };
一串“#”字符看起来比一串“+”或“*”更暗、更突出。此外,这些字符与字体有关,
只有当字体类型设置为“Courier New”时,此应用程序生成的 ASCII 艺术图才会好看。
此外,两个相邻行的相对间距显然大于两个相邻字符。这会导致 ASCII 图像在高度上拉伸。
为了消除这种情况,我从图像的高度中抽取行,并通过交替设置切换标志插入换行符。
最后,将用 <pre></pre> 标记括起来以保留格式的字符串加载到浏览器控件中。
如果用户想要将其保存为纯文本文件,则所有出现的
都将被空格替换,所有换行符“<BR>”都将被“\n”替换。
private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog1.Filter = "Text File (*.txt)|.txt|HTML (*.htm)|.htm";
DialogResult diag = saveFileDialog1.ShowDialog();
if (diag == DialogResult.OK)
{
if (saveFileDialog1.FilterIndex == 1)
{
_Content = _Content.Replace(" ", " ").Replace("<BR>","\n");
}
else
{
_Content = "<pre>" + _Content + "</pre>";
}
StreamWriter sw = new StreamWriter(saveFileDialog1.FileName);
sw.Write(_Content);
sw.Flush();
sw.Close();
}
}
结论
这是 .NET 中 GDI+ 可以实现的众多有趣功能之一。代码可以进一步增强,
以生成彩色或动画 ASCII 艺术。我试图使其简单明了,以便于理解。
编码真的很有趣,所以玩得开心吧!!
原文地址:https://blog.csdn.net/ljygood2/article/details/144322290
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!