先看一下效果圖
在Main方法中調用(首先要添加程序集System.Drawing,然后引入命名空間System.Drawing)
ConvertToChar(new Bitmap(@"D:\img\dlrb.png"), @"D:\1.txt", 2, 3);
Console.WriteLine("Success");
方法,這說一下,因為大圖片像素的寬和高都是1000以上的,所以每一個轉換為字符的話,會變得很寬,所以后兩個參數是指定寬度和高度縮小WAddNum和HAddNum倍
/// <summary>
/// 將圖片轉換為字符畫
/// </summary>
/// <param name="bitmap">Bitmap類型的對象</param>
/// <param name="savaPath">保存路徑</param>
/// <param name="WAddNum">寬度縮小倍數(如果輸入3,則以1/3倍的寬度顯示)</param>
/// <param name="HAddNum">高度縮小倍數(如果輸入3,則以1/3倍的高度顯示)</param>
public static void ConvertToChar(Bitmap bitmap, String savaPath, int WAddNum, int HAddNum) {
StringBuilder sb = new StringBuilder(); String replaceChar = "@*#$%XB0H?OC7>+v=~^:_-'`. "; for (int i = 0; i < bitmap.Height; i += HAddNum) { for (int j = 0; j < bitmap.Width; j += WAddNum) { //獲取當前點的Color對象 Color c = bitmap.GetPixel(j, i); //計算轉化過灰度圖之后的rgb值(套用已有的計算公式就行) int rgb = (int)(c.R * .3 + c.G * .59 + c.B * .11); //計算出replaceChar中要替換字符的index //所以根據當前灰度所占總rgb的比例(rgb值最大為255,為了防止超出索引界限所以/256.0) //(肯定是小於1的小數)乘以總共要替換字符的字符數,獲取當前灰度程度在字符串中的復雜程度 int index = (int)(rgb / 256.0 * replaceChar.Length); //追加進入sb sb.Append(replaceChar[index]); } //添加換行 sb.Append("\r\n"); } //創建文件流 using (FileStream fs = new FileStream(savaPath, FileMode.Create, FileAccess.Write)) { //轉碼 byte[] bs = Encoding.Default.GetBytes(sb.ToString()); //寫入 fs.Write(bs, 0, bs.Length); } }
其是內部的原理就是循環遍歷圖片的每一個像素點,然后根據計算公式計算出該點的灰度值(計算公式 R*0.3+G*0.59+B*0.11 ),計算出來之后查看占總值(255)的多少,結果肯定不足1,因為計算出來的值最大為255,然后接下來就是查找對應的字符,其實字符根據復雜的程度已經排好序了,有幾個字符就是將255分成幾份,比如這里就是將字符分成了26份,用計算出來的小數✖總字符的長度找到。
舉個例子:例如rgb值都為255,計算出來灰度的值也為255,然后除以256.0,此時結果是一個小數0.99....,然后在✖26,結果是25.74....,轉換為int之后為索引為25,剛好是最后一位。