Click here to Skip to main content
Click here to Skip to main content

Image to Characters Converter using Intensity

, 17 Oct 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
This article shows how you can display a picture in digits 1 and 0.

Introduction

The main idea is about reading the intensity value of every group of the picture. (The mentioned group is a matrix formed from the adjacent pixels.) Then writing a digit either 1 or 0 and its color value is the average intensity value of the source group.

Background

First of all we have to distinguish between how the intensity is obtained, in this article I'll going to show two methods either:

  1. 1st intensity method (gives better visual results): in this method, intensity is obtained from the first pixel of the group.
  2. Average intensity method: while here we calculate the average intensity value of each group.

In both methods, after we get the intensity value we write a digit either 1 or 0 and its color value is the value which we got.

The previous mechanism is applied to the image by reading it as a matrix (2D array). Noticing that traversing through the array is "for each row of the image, visit each pixel".

The next figuures show the differences between the two methods:

WindowsLogo.jpg
Original picture

 

WindowsLogoDigits.gif WindowsLogoDigits.gif
1st intensity method Average intensity method

Using the Code

Tools class:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace Image2Characters
{
    public static class Tools
    {
        /// <summary>
        /// folder names both input and output folder
        /// </summary>
        static String strImagesFolderName = "images";
        static String strHtmlFolderName = "pages";

        /// <summary>
        /// Result html file content
        /// </summary>
        static String strHtmlFileHeader = "<html><head><title>{0} Image - {1}</title></head><body><pre><font><font style=\"font-size: 9px;\">";
        static String strHtmlFileFooter = "</font></font></pre></body></html>";

        /// <summary>
        /// How many pixels fit in each group
        /// here the group size is 12 * 5
        /// </summary>
        static int iWidthRatio = 5, iHeightRatio = 12;



        /// <summary>
        /// Make sure program needed directories is exists
        /// </summary>
        public static void InitEnviroment()
        {
            Directory.CreateDirectory(strImagesFolderName);
            Directory.CreateDirectory(strHtmlFolderName);
        }

        /// <summary>
        /// Calculates the Intensity of each given pixel
        /// </summary>
        /// <param name="color">the image pixel</param>
        /// <returns>the Intensity</returns>
        public static int GetIntensity(Color color)
        {
            return (int)(0.3f * color.R + 0.59f * color.G + 0.11f * color.B);
        }

        /// <summary>
        /// Retrieves the available images that should be converted
        /// </summary>
        /// <returns></returns>
        public static String[] GetImages()
        {
            return Directory.GetFiles(strImagesFolderName + @"\", "*.jpg");
        }

        /// <summary>
        /// Converts a given image file to its matching html file
        /// in "pages" folder using "1st Intensity" value
        /// </summary>
        /// <param name="strImageName">Image to be converted path</param>
        public static void ConvertImageToCharacter1stIntensity(String strImageName)
        {
            Bitmap img = (Bitmap)Image.FromFile(strImageName);
            String strDigit = ""
                , strImageNameWithoutExtension = Path.GetFileNameWithoutExtension(strImageName);
            StringBuilder createdFileContent = new StringBuilder();

            int k = 0; // for switching between 1 and 0

            createdFileContent.AppendFormat(strHtmlFileHeader, strImageNameWithoutExtension, System.Windows.Forms.Application.ProductName);

            // looping through the image
            for (int i = 0; i < img.Height - 1; i += iHeightRatio)
            {
                for (int j = 0; j < img.Width - 1; j += iWidthRatio)
                {
                    strDigit = (k % 2 == 0) ? "0" : "1";

                    k++;

                    createdFileContent.AppendFormat("<font color=\"#{0:x2}{0:x2}{0:x2}\">{1}</font>", Tools.GetIntensity(img.GetPixel(j, i)), strDigit);
                }
                createdFileContent.Append("<br/>");
            }

            createdFileContent.Append(strHtmlFileFooter);

            // save html output file in "pages" folder
            File.WriteAllText(String.Format(@"{0}\{1}.html", strHtmlFolderName, strImageNameWithoutExtension), createdFileContent.ToString());
        }

        /// <summary>
        /// Converts a given image file to its matching html file
        /// in "pages" folder using "Average Intensity" value
        /// </summary>
        /// <param name="strImageName">Image to be converted path</param>
        public static void ConvertImageToCharacterAverageIntensity(String strImageName)
        {
            Bitmap img = (Bitmap)Image.FromFile(strImageName);
            String strDigit = ""
                , strImageNameWithoutExtension = Path.GetFileNameWithoutExtension(strImageName);
            StringBuilder createdFileContent = new StringBuilder();

            int iAverageValue // intensity average value for each group
                , k = 0 // for switching between 1 and 0
                , iItemsCountInSubMatrix = iWidthRatio * iHeightRatio // the count of elements in group
                , iSubMatrixElementsSum; // the total value of group elements

            createdFileContent.AppendFormat(strHtmlFileHeader, strImageNameWithoutExtension, System.Windows.Forms.Application.ProductName);

            // looping through the image
            for (int i = 0; i < img.Height - 1; i += iHeightRatio)
            {
                for (int j = 0; j < img.Width - 1; j += iWidthRatio)
                {
                    iSubMatrixElementsSum = 0;
                    // looping inside the group
                    for (int i2 = 0; i2 < iHeightRatio - 1; i2++)
                    {
                        if (i + i2 < img.Height)
                        {
                            for (int j2 = 0; j2 < iWidthRatio - 1; j2++)
                            {
                                if (j + j2 < img.Width)
                                {
                                    iSubMatrixElementsSum += Tools.GetIntensity(img.GetPixel(j + j2, i + i2));
                                }
                            }
                        }
                    }
                    // calculating the average intensity value
                    iAverageValue = iSubMatrixElementsSum / iItemsCountInSubMatrix;

                    strDigit = (k % 2 == 0) ? "0" : "1";

                    k++;

                    createdFileContent.AppendFormat("<font color=\"#{0:x2}{0:x2}{0:x2}\">{1}</font>", iAverageValue, strDigit);
                }
                createdFileContent.Append("<br/>");
            }

            createdFileContent.Append(strHtmlFileFooter);

            // save html output file in "pages" folder
            File.WriteAllText(String.Format(@"{0}\{1}.html", strHtmlFolderName, strImageNameWithoutExtension), createdFileContent.ToString());
        }
    }
}

History

  • v1.0 15/10/08

Notices

  • The only accepted images are the ones that end with the "jpg" extension due to the implementation of my code.
  • I chose the size of the group to be 12 rows and 5 columns. You can change these values if you didn't get the desired result. Either you can set them to 1 row and 1 column, this will map each pixel to a digit; of course this will give a bigger picture.
  • This project is using C# 2.0 but was coded in Visual Studio 2008.
  • I write "1st intensity method" from my practical tries, meaning this is not a referential contrary to "Average intensity method" that is a simple well known method. But I prefered to write "1st intensity method" because it showed better results.

Improvements

  • Change the group size to be related to the size of the source image. This improvement will reduce the bad results when the source image is small. For example: width = 80~110px. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Redwan AlBougha
Software Developer
Syrian Arab Republic Syrian Arab Republic
I'm currently studying IT engineering. My general computer skills can be outlined :
 
• Programming languages :
C/C++, C#, Databases(Oracle and MySQL), PHP, ASP.NET.
 
• Operating systems :
Windows and Linux
 
• Frameworks and environments :
Borland development environment (C++), Windows SDK/Shell/GDI, MFC
 
• Programs and tools :
Adobe Dreamweaver, Adobe Photoshop, Adobe Flash
 
• Also :
Web Development skills (HTML, CSS, Javascript).
 
I'm interested in computer vision applications. Also I'm giving some tries to OS programming.
 
I hope to gain both the applied and theoretical knowledge of image processing field.

Comments and Discussions

 
QuestionAny comments ?? PinmemberRedwan Al-Bougha17-Oct-08 16:42 
AnswerRe: Any comments ?? PinmemberTobiasP21-Oct-08 0:52 
GeneralRe: Any comments ?? PinmemberRedwan Al-Bougha21-Oct-08 5:04 
GeneralRe: Any comments ?? PinmemberRedwan Al-Bougha22-Oct-08 15:01 
GeneralRe: Any comments ?? PinmemberTobiasP23-Oct-08 1:36 
GeneralRe: Any comments ?? PinmemberRedwan Al-Bougha23-Oct-08 1:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 17 Oct 2008
Article Copyright 2008 by Redwan AlBougha
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid