Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Visual Cryptography Generator

0.00/5 (No votes)
22 Oct 2007 1  
Visual cryptography is a cryptographic technique which allows visual information (pictures, text, etc.) to be encrypted in such a way that the decryption can be performed by the human visual system, without the aid of computers.

Image 1

Screenshot - codeproject0.png

Image 2

Screenshot - codeproject1.png

After Combining 2 Images

Screenshot - codeproject.png

Introduction

I should say "Thank you" to tectures, I write this article because of his idea.

Before writing this article, I've written an article about alpha in PNG to make a magic card for friends and tectures asked me what's the different between my program and Visual cryptography. Actually, in that article I didn't think about encrypting anything inside the image, it just did a simple track and made your friends happy.

And I found that no one had written this before, so I've made a simple program to represent this concept.

Background

Visual cryptography was introduced by Naor and Shamir at EUROCRYPT '94. They asked the following intriguing question: is it possible to devise a secret sharing scheme in which an image can be reconstructed "visually" by superimposing two shares? Each share would consist of a transparency, made up of black and white pixels. (Note that it would be more accurate to say "transparent" rather than "white".) Examination of one share should reveal no information about the image.

For more details, please read this.

Using the Code

Two constant variables that need to be defined are as follows:

private Size IMAGE_SIZE = new Size(437, 106); //Image size
private const int GENERATE_IMAGE_COUNT = 2; //How many images you would like to generate

The following function generates the shared image:

private Bitmap[] GenerateImage(string inputText)
{
    Bitmap finalImage = new Bitmap(IMAGE_SIZE.Width, IMAGE_SIZE.Height);
    Bitmap tempImage = new Bitmap(IMAGE_SIZE.Width / 2, IMAGE_SIZE.Height);
    Bitmap[] image = new Bitmap[GENERATE_IMAGE_COUNT];
    
    Random rand = new Random();
    SolidBrush brush = new SolidBrush(Color.Black);
    Point mid = new Point(IMAGE_SIZE.Width / 2, IMAGE_SIZE.Height / 2);
    Graphics g = Graphics.FromImage(finalImage);
    Graphics gtemp = Graphics.FromImage(tempImage);

    //set text format
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;
    Font font = new Font("Times New Roman", 48);

    Color fontColor;
    g.DrawString(inputText, font, brush, mid, sf);
    gtemp.DrawImage(finalImage, 0, 0, tempImage.Width, tempImage.Height);
    for (int i = 0; i < image.Length; i++)
    {
        image[i] = new Bitmap(IMAGE_SIZE.Width, IMAGE_SIZE.Height);
    }
    
    int index = -1;
    int width = tempImage.Width;
    int height = tempImage.Height;
    for (int x = 0; x < width; x += 1)
    {
        for (int y = 0; y < height; y += 1)
        {
            fontColor = tempImage.GetPixel(x, y);
            index = rand.Next(image.Length);

            //Check if the color empty
            if (fontColor.Name == Color.Empty.Name)
            {
                for (int i = 0; i < image.Length; i++)
                {
                    if (index == 0)
                    {
                        image[i].SetPixel(x * 2, y, Color.Black);
                        image[i].SetPixel(x * 2 + 1, y, Color.Empty);
                    }
                    else
                    {
                        image[i].SetPixel(x * 2, y, Color.Empty);
                        image[i].SetPixel(x * 2 + 1, y, Color.Black);
                    }
                }
            }
            else
            {
                for (int i = 0; i < image.Length; i++)
                {
                    if ((index + i) % image.Length == 0)
                    {
                        image[i].SetPixel(x * 2, y, Color.Black);
                        image[i].SetPixel(x * 2 + 1, y, Color.Empty);
                    }
                    else
                    {
                        image[i].SetPixel(x * 2, y, Color.Empty);
                        image[i].SetPixel(x * 2 + 1, y, Color.Black);
                    }
                }
            }
        }
    }

    //Clean Up
    brush.Dispose();
    tempImage.Dispose();
    finalImage.Dispose();

    return image;
}

Points of Interest

They demonstrated a visual secret sharing scheme, where an image was broken up into n shares so that only someone with all n shares could decrypt the image, while any n-1 shares revealed no information about the original image. Each share was printed on a separate transparency, and decryption was performed by overlaying the shares. When all n shares were overlayed, the original image would appear.

History

  • 23rd October, 2007: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here