/// <summary>Create the arrays of best CharacterValues</summary> private void CreateCharacterArrays() { _BestCharacter = new CharacterValue[256, _MaxCharWidth + 1]; _BestCharacterDiff = new int[256, _MaxCharWidth + 1]; for (int currentwidth = 0; currentwidth < _MaxCharWidth + 1; currentwidth++) { if (_UsedWidths[currentwidth]) { for (int currentvalue = 0; currentvalue < 256; currentvalue++) { CharacterValue bestcharacter = new CharacterValue(); int bestdifference = 256; for (int currentcharpos = 0; currentcharpos < characters.Length; currentcharpos++) { if (characters[currentcharpos].Width == currentwidth) { int chardifference = _DiffArray[characters[currentcharpos].Value, currentvalue]; if (chardifference < bestdifference) { bestcharacter = characters[currentcharpos]; bestdifference = chardifference; } } } _BestCharacter[!_InvertOutput ? currentvalue : 255 - currentvalue, currentwidth] = bestcharacter; _BestCharacterDiff[!_InvertOutput ? currentvalue : 255 - currentvalue, currentwidth] = bestdifference; } } } }
/// <summary> /// Convert 2d array of byte values into character strings /// </summary> /// <param name="values">2d array of values that represent the image</param> /// <returns>Array of strings containing the text image</returns> public override string[] Apply(byte[,] values) { if (values == null) { return(null); } int ArrayWidth = values.GetLength(0); int ArrayHeight = values.GetLength(1); if (ArrayWidth < 1 || ArrayHeight < 1) { return(null); } // the corresponding character position for every possible output pixel int[] PixelToCharPos = new int[(ArrayWidth * CharacterWidth) + _MaxCharWidth]; for (int charpos = 0, pixelpos = 0; charpos < ArrayWidth; charpos++) { for (int z = 0; z < CharacterWidth; z++) { PixelToCharPos[pixelpos++] = charpos; } } for (int x = ArrayWidth * CharacterWidth; x < (ArrayWidth * CharacterWidth) + _MaxCharWidth; x++) { PixelToCharPos[x] = ArrayWidth - 1; } string[] Result = new string[ArrayHeight]; int targetwidth = ArrayWidth * CharacterWidth; int charwidtharraysize = _MaxCharWidth + 1; int[] PostionValues = new int[charwidtharraysize]; for (int row = 0; row < ArrayHeight; row++) { int XPosition = 0; StringBuilder builder = new StringBuilder(); while (XPosition < targetwidth) { int Total = 0; for (int x = 1; x < charwidtharraysize; x++) { Total += values[PixelToCharPos[XPosition + x], row]; if (_UsedWidths[x]) { PostionValues[x] = _AverageArray[Total, x]; } } CharacterValue bestfit = _BestCharacter[PostionValues[_MaxCharWidth], _MaxCharWidth]; int bestdiff = _BestCharacterDiff[PostionValues[_MaxCharWidth], _MaxCharWidth]; for (int x = 1; x < charwidtharraysize; x++) { if (_UsedWidths[x]) { if (_BestCharacterDiff[PostionValues[x], x] < bestdiff) { bestfit = _BestCharacter[PostionValues[x], x]; bestdiff = _BestCharacterDiff[PostionValues[x], x]; } } } builder.Append(bestfit.Character); XPosition += bestfit.Width; } Result[row] = builder.ToString(); } return(Result); }
/// <summary>Update the arrays for the current Font</summary> private void UpdateFontArrays() { ArrayList newcharacters = new ArrayList(); int min = 255; int max = 0; _MaxCharWidth = 0; for (int currentcharpos = 0; currentcharpos < ValidCharacters.Length; currentcharpos++) { CharacterValue current = new CharacterValue(ValidCharacters[currentcharpos], _Font); if (current.Value > -1) { newcharacters.Add(current); if (current.Value > max) { max = current.Value; } if (current.Value < min) { min = current.Value; } if (current.Width > _MaxCharWidth) { _MaxCharWidth = current.Width; } } } _AverageArray = new int[256 * (_MaxCharWidth + 1), _MaxCharWidth + 1]; for (int x = 0; x < 256 * (_MaxCharWidth + 1); x++) { for (int y = 1; y < (_MaxCharWidth + 1); y++) { _AverageArray[x, y] = (int)(((float)x / (float)y) + 0.5f); } } float ratio = 255f / (float)(max - min); ArrayList list = new ArrayList(); _UsedWidths = new bool[_MaxCharWidth + 1]; foreach (CharacterValue charvalue in newcharacters) { int newvalue = (int)(((float)(charvalue.Value - min) * ratio) + 0.5f); list.Add(new CharacterValue(charvalue.Character, charvalue.Width, newvalue)); _UsedWidths[charvalue.Width] = true; } newcharacters = new ArrayList(); foreach (CharacterValue oldvalue in list) { bool match = false; foreach (CharacterValue charvalue in newcharacters) { if (charvalue.Value == oldvalue.Value && charvalue.Width == oldvalue.Width) { // TODO: check which character is better (covers more of the area?) match = true; break; } } if (!match) { newcharacters.Add(oldvalue); } } characters = (CharacterValue[])newcharacters.ToArray(typeof(CharacterValue)); }
/// <summary>Update the arrays for the current Font</summary> private void UpdateFontArrays() { ArrayList newcharacters = new ArrayList(); int min = 255; int max = 0; _MaxCharWidth = 0; for (int currentcharpos = 0; currentcharpos < ValidCharacters.Length; currentcharpos++) { CharacterValue current = new CharacterValue(ValidCharacters[currentcharpos], _Font); if (current.Value > -1) { newcharacters.Add(current); if (current.Value > max) max = current.Value; if (current.Value < min) min = current.Value; if (current.Width > _MaxCharWidth) _MaxCharWidth = current.Width; } } _AverageArray = new int[256 * (_MaxCharWidth + 1), _MaxCharWidth + 1]; for (int x = 0; x < 256 * (_MaxCharWidth + 1); x++) { for (int y = 1; y < (_MaxCharWidth + 1); y++) { _AverageArray[x, y] = (int)(((float)x / (float)y) + 0.5f); } } float ratio = 255f / (float)(max - min); ArrayList list = new ArrayList(); _UsedWidths = new bool[_MaxCharWidth + 1]; foreach (CharacterValue charvalue in newcharacters) { int newvalue = (int)(((float)(charvalue.Value - min) * ratio) + 0.5f); list.Add(new CharacterValue(charvalue.Character, charvalue.Width, newvalue)); _UsedWidths[charvalue.Width] = true; } newcharacters = new ArrayList(); foreach (CharacterValue oldvalue in list) { bool match = false; foreach (CharacterValue charvalue in newcharacters) { if (charvalue.Value == oldvalue.Value && charvalue.Width == oldvalue.Width) { // TODO: check which character is better (covers more of the area?) match = true; break; } } if (!match) { newcharacters.Add(oldvalue); } } characters = (CharacterValue[])newcharacters.ToArray(typeof(CharacterValue)); }
/// <summary> /// Create an ASCII Ramp with from the given font and characters /// </summary> /// <param name="font">Font to be used</param> /// <param name="characters">The characters to be used for the ramp</param> /// <returns>A new ASCII ramp</returns> public static string CreateRamp(Font font, string characters) { if (characters == null || characters.Length < 1) return null; if (characters.Length == 1) return characters; string characterstring = ""; foreach (char c in characters.ToCharArray()) { if (characterstring.IndexOf(c) == -1) { characterstring += c.ToString(); } } System.Collections.SortedList list = new System.Collections.SortedList(); int min = 255; int max = 0; CharacterValue charval; for (int i = 0; i < characterstring.Length; i++) { charval = new CharacterValue(characterstring[i], font); if (list.ContainsKey(charval.Value)) { if (charval.Score < ((CharacterValue)list[charval.Value]).Score) { list[charval.Value] = charval; } } else { if (charval.Value < min) min = charval.Value; if (charval.Value > max) max = charval.Value; list.Add(charval.Value, charval); } } list.TrimToSize(); string result = ""; System.Collections.IDictionaryEnumerator idenu = list.GetEnumerator(); // move to the first object idenu.MoveNext(); int current = (int)idenu.Key; int next, mid; // loop through and fill in the gaps while (idenu.MoveNext()) { next = (int)idenu.Key; mid = ((next - current) / 2) + current; for (int i = current; i < mid; i++) { result += list[current]; } for (int i = mid; i < next; i++) { result += list[next]; } current = next; } return result; }
/// <summary> /// Create an ASCII Ramp with from the given font and characters /// </summary> /// <param name="font">Font to be used</param> /// <param name="characters">The characters to be used for the ramp</param> /// <returns>A new ASCII ramp</returns> public static string CreateRamp(Font font, string characters) { if (characters == null || characters.Length < 1) { return(null); } if (characters.Length == 1) { return(characters); } string characterstring = ""; foreach (char c in characters.ToCharArray()) { if (characterstring.IndexOf(c) == -1) { characterstring += c.ToString(); } } System.Collections.SortedList list = new System.Collections.SortedList(); int min = 255; int max = 0; CharacterValue charval; for (int i = 0; i < characterstring.Length; i++) { charval = new CharacterValue(characterstring[i], font); if (list.ContainsKey(charval.Value)) { if (charval.Score < ((CharacterValue)list[charval.Value]).Score) { list[charval.Value] = charval; } } else { if (charval.Value < min) { min = charval.Value; } if (charval.Value > max) { max = charval.Value; } list.Add(charval.Value, charval); } } list.TrimToSize(); string result = ""; System.Collections.IDictionaryEnumerator idenu = list.GetEnumerator(); // move to the first object idenu.MoveNext(); int current = (int)idenu.Key; int next, mid; // loop through and fill in the gaps while (idenu.MoveNext()) { next = (int)idenu.Key; mid = ((next - current) / 2) + current; for (int i = current; i < mid; i++) { result += list[current]; } for (int i = mid; i < next; i++) { result += list[next]; } current = next; } return(result); }