12,405,543 members (60,042 online)
alternative version

23.1K views
31 bookmarked
Posted

# Image to Characters Converter using Intensity

, 17 Oct 2008 CPOL
 Rate this:
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:

 Original picture

 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 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

// 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

// 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.

## Share

 Software Developer 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 :

• 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.

## You may also be interested in...

 First Prev Next
 Any comments ?? Redwan Al-Bougha17-Oct-08 15:42 Redwan Al-Bougha 17-Oct-08 15:42
 Re: Any comments ?? TobiasP20-Oct-08 23:52 TobiasP 20-Oct-08 23:52
 Re: Any comments ?? Redwan Al-Bougha21-Oct-08 4:04 Redwan Al-Bougha 21-Oct-08 4:04
 Re: Any comments ?? Redwan Al-Bougha22-Oct-08 14:01 Redwan Al-Bougha 22-Oct-08 14:01
 Re: Any comments ?? TobiasP23-Oct-08 0:36 TobiasP 23-Oct-08 0:36
 Re: Any comments ?? Redwan Al-Bougha23-Oct-08 0:49 Redwan Al-Bougha 23-Oct-08 0:49
 Last Visit: 31-Dec-99 18:00     Last Update: 29-Jul-16 8:38 Refresh 1