一、老规矩,先看效果:
1、原图一
生成效果图一:
2、原图二
生成效果图二:
3、原图三:
生成效果图三之1:
效果图三之2:
说明:图三中同样的原图,生成的ASCII字符串大小不同,因为所取参数不同。
二、关键源代码:
// 调整行距: AdjustLineSpace.cs
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Com.BrawDraw.Controls.Helper
{
public static class AdjustLineSpace
{
public const int WM_USER = 0x0400;
public const int EM_GETPARAFORMAT = WM_USER + 61;
public const int EM_SETPARAFORMAT = WM_USER + 71;
public const long MAX_TAB_STOPS = 32;
public const uint PFM_LINESPACING = 0x00000100;
[StructLayout(LayoutKind.Sequential)]
private struct PARAFORMAT2
{
public int cbSize;
public uint dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
public int dySpaceBefore;
public int dySpaceAfter;
public int dyLineSpacing;
public short sStyle;
public byte bLineSpacingRule;
public byte bOutlineLevel;
public short wShadingWeight;
public short wShadingStyle;
public short wNumberingStart;
public short wNumberingStyle;
public short wNumberingTab;
public short wBorderSpace;
public short wBorderWidth;
public short wBorders;
}
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref PARAFORMAT2 lParam);
/// <summary>
/// 调整行距。使用方法:SetLineSpace(richTextBox1, 40);
/// </summary>
/// <param name="ctl">控件</param>
/// <param name="height">要指定的行高像素</param>
public static void SetLineSpace(Control ctl, int height)
{
//1像素=15缇。
int dyLineSpacing = height * 15;
//4:dylinespace成员以 缇。的形式指定从一行到下一行的间距。控件使用指定的精确间距,即使dylinespace指定的值小于单个间距。
//3:dylinespace成员以 缇。的形式指定从一行到下一行的间隔。但是,如果dylinespace指定的值小于单间距,则控件将显示单间距文本。
byte bLineSpacingRule = (byte)3;
PARAFORMAT2 fmt = new PARAFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.bLineSpacingRule = bLineSpacingRule;
fmt.dyLineSpacing = dyLineSpacing;
fmt.dwMask = PFM_LINESPACING;
try
{
SendMessage(new HandleRef(ctl, ctl.Handle), EM_SETPARAFORMAT, bLineSpacingRule, ref fmt);
}
catch
{ }
}
}
}
/// <summary>
/// 将图像转为ASCII字符串
/// </summary>
/// <param name="stream"></param>
/// <param name="ImageSize"></param>
/// <param name="Quick"></param>
/// <returns></returns>
public static string ConvertImageToASCii(Stream stream, int ImageSize, bool isQuick)
{
int num;
StringBuilder builder = new StringBuilder();
Image original = Image.FromStream(stream);
Bitmap image = new Bitmap(original, new Size(original.Width, original.Height));
original.Dispose();
Rectangle destRect = new Rectangle(0, 0, image.Width, image.Height);
ColorMatrix newColorMatrix = new ColorMatrix();
newColorMatrix[0, 0] = 0.3333333f;
newColorMatrix[0, 1] = 0.3333333f;
newColorMatrix[0, 2] = 0.3333333f;
newColorMatrix[1, 0] = 0.3333333f;
newColorMatrix[1, 1] = 0.3333333f;
newColorMatrix[1, 2] = 0.3333333f;
newColorMatrix[2, 0] = 0.3333333f;
newColorMatrix[2, 1] = 0.3333333f;
newColorMatrix[2, 2] = 0.3333333f;
ImageAttributes imageAttr = new ImageAttributes();
imageAttr.SetColorMatrix(newColorMatrix);
Graphics graphics = Graphics.FromImage(image);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttr);
graphics.Dispose();
switch (ImageSize)
{
case 1:
num = 1;
break;
case 2:
num = 2;
break;
case 3:
num = 6;
break;
case 4:
num = 8;
break;
case 5:
num = 10;
break;
default:
num = 3;
break;
}
int num2 = num * 2;
int num3 = num * num2;
for (int i = 0; i < (image.Height / num2); i++)
{
builder.Append("\t");
int num5 = i * num2;
for (int j = 0; j < (image.Width / num); j++)
{
int x = j * num;
int num8 = 0;
if (isQuick)
{
for (int k = 0; k < num; k++)
{
try
{
int num10 = (int)(image.GetPixel(x, k + num5).GetBrightness() * 100f);
num8 += num10;
}
catch
{
num8 += 50;
}
}
}
else
{
for (int m = 0; m < num; m++)
{
for (int n = 0; n < num2; n++)
{
int y = m + num5;
int num14 = n + x;
try
{
int num15 = (int)(image.GetPixel(num14, y).GetBrightness() * 100f);
num8 += num15;
}
catch
{
num8 += 50;
}
}
}
}
int num16 = num8 / num3;
if (num16 < 10)
{
builder.Append("#");
}
else if (num16 < 17)
{
builder.Append("@");
}
else if (num16 < 24)
{
builder.Append("&");
}
else if (num16 < 31)
{
builder.Append("$");
}
else if (num16 < 38)
{
builder.Append("%");
}
else if (num16 < 45)
{
builder.Append("|");
}
else if (num16 < 52)
{
builder.Append("!");
}
else if (num16 < 59)
{
builder.Append(";");
}
else if (num16 < 66)
{
builder.Append(":");
}
else if (num16 < 73)
{
builder.Append("'");
}
else if (num16 < 80)
{
builder.Append("`");
}
else if (num16 < 87)
{
builder.Append(".");
}
else
{
builder.Append(" ");
}
}
builder.Append("\n");
}
image.Dispose();
return builder.ToString();
}
附:图片转ASCII图案: 图片转ASCII图案_刨坟专员的博客-CSDN博客_ascii图案
转载:https://blog.csdn.net/johnsuna/article/details/125651878