/// <summary> /// Update the arrays for the current Font /// </summary> private void CreateCharacterArray() { int minimumValue = 255; int maximumValue = 0; this.maximumCharacterWidth = 0; VariableWidthCharacterValue[] characterValues = new VariableWidthCharacterValue[this.ValidCharacters.Length]; for (int i = 0; i < this.ValidCharacters.Length; i++) { characterValues[i] = new VariableWidthCharacterValue(this.ValidCharacters[i], this.font); if (maximumValue < characterValues[i].Value) { maximumValue = characterValues[i].Value; } if (minimumValue > characterValues[i].Value) { minimumValue = characterValues[i].Value; } if (characterValues[i].Width > this.maximumCharacterWidth) { this.maximumCharacterWidth = characterValues[i].Width; } } float ratio = 255f / (float)(maximumValue - minimumValue); this.widthHasBeenUsed = new bool[this.maximumCharacterWidth + 1]; List <VariableWidthCharacterValue> list = new List <VariableWidthCharacterValue>(); for (int i = 0; i < characterValues.Length; i++) { // stretch the characters value to range from 0 to 255 characterValues[i].Value = (int)(((float)(characterValues[i].Value - minimumValue) * ratio) + 0.5f); this.widthHasBeenUsed[characterValues[i].Width] = true; bool uniqueCharacter = true; foreach (VariableWidthCharacterValue value in list) { // dont add the character if one with that width and value is already in the list if (characterValues[i].Width == value.Width && characterValues[i].Value == value.Value) { uniqueCharacter = false; break; } } if (uniqueCharacter) { list.Add(characterValues[i]); } } this.characters = list.ToArray(); }
/// <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 numberOfColumns = values[0].Length; int numberOfRows = values.Length; if (numberOfColumns < 1 || numberOfRows < 1) { return(null); } int targetWidth = numberOfColumns * CharacterWidth; // the corresponding character position for every output pixel int[] pixelToCharacterPosition = new int[targetWidth + this.maximumCharacterWidth]; for (int characterPosition = 0, pixelPosition = 0; characterPosition < numberOfColumns; characterPosition++) { for (int i = 0; i < CharacterWidth; i++) { pixelToCharacterPosition[pixelPosition++] = characterPosition; } } // set the overlapping pixels to the last character for (int x = targetWidth; x < targetWidth + this.maximumCharacterWidth; x++) { pixelToCharacterPosition[x] = numberOfColumns - 1; } string[] result = new string[numberOfRows]; int characterWidthArraySize = this.maximumCharacterWidth + 1; int[] postionValues = new int[characterWidthArraySize]; for (int row = 0; row < numberOfRows; row++) { int position = 0; StringBuilder builder = new StringBuilder(); while (position < targetWidth) { for (int width = 1, total = 0; width < characterWidthArraySize; width++) { total += values[row][pixelToCharacterPosition[position + width]]; if (!this.widthHasBeenUsed[width]) { continue; } postionValues[width] = this.averageArray[total][width]; } VariableWidthCharacterValue bestFit = this.bestCharacter[postionValues[this.maximumCharacterWidth]][this.maximumCharacterWidth]; int bestDifference = this.bestCharacterDifference[postionValues[this.maximumCharacterWidth]][this.maximumCharacterWidth]; for (int x = 1; x < characterWidthArraySize; x++) { if (!this.widthHasBeenUsed[x] || this.bestCharacterDifference[postionValues[x]][x] >= bestDifference) { continue; } bestFit = this.bestCharacter[postionValues[x]][x]; bestDifference = this.bestCharacterDifference[postionValues[x]][x]; } builder.Append(bestFit.Character); position += bestFit.Width; } result[row] = builder.ToString(); } return(result); }