// Se puede jugar con las resoluciones de imagen para ver cual da mejores resultados? public static Image Convert2ASCII(Image BW_Image, List <WeightedChar> characters, out List <List <string> > ResultText) { /* * ALGORITHM: * * 1- Get target Image size (w=Width,h=Height) * 2- Create Result Image with white background and size W = w*character_image_width * H = h*character_image_height * 3- Create empty string to hold the text * * 4- for (int j=0;j=target_Image_Height;j++) --> ALL ROWS * 5- Create row text string * for (int i=0;i=target_Image_Width;i++) --> ALL COLUMNS * 6- Get target pixel weight * 7- Get closest weight from character list * 8- Paste character image in position w = i*character_image_width * h = j*character_image_height * ¡¡ Be careful with coordinate system when placing Images !! * 9- Add (string)character to row text string * 10- Add row text string to text holding string * 11 - return resulting Image & Text */ Image ResultImage = new Bitmap(BW_Image.Width * characters[0].CharacterImage.Width, BW_Image.Height * characters[0].CharacterImage.Height); Graphics drawing = Graphics.FromImage(ResultImage); drawing.Clear(Color.White); ResultText = new List <List <string> > { }; Bitmap BlackAndWhite = (Bitmap)BW_Image; for (int j = 0; j < BW_Image.Height; j++) // ROW { List <string> RowText = new List <string> { }; for (int i = 0; i < BW_Image.Width; i++) // COLUMN { Color pixel = BlackAndWhite.GetPixel(i, j); double targetvalue = (pixel.R + pixel.G + pixel.B) / 3; WeightedChar closestchar = characters.Where(t => Math.Abs(t.Weight - targetvalue) == characters.Min(e => Math.Abs(e.Weight - targetvalue))).FirstOrDefault(); RowText.Add(closestchar.Character); drawing.DrawImage(closestchar.CharacterImage, i * closestchar.CharacterImage.Width, j * closestchar.CharacterImage.Height); } ResultText.Add(RowText); } drawing.Dispose(); return((Image)ResultImage); }
/* * The methods contained in this class are executed at the inizialization * of the program, as the results from their calculations are needed for * the image conversion and are not user-dependent, thus not depending from * the actions taken by the user. * * It essentially does, foreach ASCII character between 32-126, the following: * - Calculate its weight, defined as: number of black pixels / number of pixels in character image * Note: To understand the process in depth, please read the code and comments below. * - Generate a square shaped image of the character, with the character in question located in the * center of the image. The character is drawn in black on top of a white background. * - Associate the character in question (char type) to its image and weight. * * All this character information (character, weight and image) is stored in a custom class (WeightedChar) * which can hold the 3 properties. * * All the classes resulting from the calculations are stored in a List so we can access the results. */ public static List <WeightedChar> GenerateFontWeights() // Collect chars, their Images and weights in a list of WeightedChar { List <WeightedChar> WeightedChars = new List <WeightedChar>(); SizeF commonsize = GetGeneralSize(); // Get standard size (nxn square), which will be common to all CharImages for (int i = 32; i <= 126; i++) // Iterate through Chars { var forweighting = new WeightedChar(); // New object to hold Image, Weight and Char of new character char c = Convert.ToChar(i); if (!char.IsControl(c)) { forweighting.Weight = GetWeight(c, commonsize); // Get character weight forweighting.Character = c.ToString(); // Get character representation (the actual char) forweighting.CharacterImage = (Bitmap)HelperMethods.DrawText(c.ToString(), Color.Black, Color.White, commonsize); // Get character Image } WeightedChars.Add(forweighting); } WeightedChars = LinearMap(WeightedChars); // Linearly map character weights to be in the range 0-255 -> mapping linearly from: MinCalcWeight - MaxCalcWeight to 0-255; // This is done to be able to directly map pixels to characters return(WeightedChars); }