Orrin Jones
Orrin Jones

Reputation: 1

How to check the image property of an pictureBox within a form in another form.

I have create a image box which changes the image within it when it is click. It is stored in form A. I now have a form b. I would like to check in form b. if the image in the picture box in form A is equal to a specific image then change the image in a picturebox in form B. I am have problems accessing the pic box in form A due to I think it being private.

Upvotes: 0

Views: 408

Answers (3)

Lemonseed
Lemonseed

Reputation: 1732

Despite the apparent simple nature of the problem, the correct way to accomplish this is deceptively complex. You may want to rethink the architecture of your application to perform this check another way, such as with an associated ID number or UUID. However, if you do in fact need to perform a content equality check on images in this manner, as follows is a basic solution that I have tested.


Since it would be painfully inefficient for us to directly compare two images to determine their equality, the best solution is to implement a simple hashing algorithm and check that instead. This is the most complicated part of the solution. To perform this automatically and abstract this step away, we can create a simple wrapper class around the standard Image object as follows:

public class ComparableImage
{
    public Image Image
    {
        get { return this.image; }
        set { SetImage(value); }
    }
    public string SHA1
    {
        get { return this.sha1; }
    }

    private Image image = null;
    private string sha1 = string.Empty;

    // This is the important part that lets us 
    // efficiently compare two images:
    public override bool Equals(object image)
    {
        if ((image != null) && (image is ComparableImage) )
        {
            return (sha1.Equals(((ComparableImage)image).sha1));
        }
        else return false;
    }

    public override int GetHashCode()
    {
        return sha1.GetHashCode();
    }

    private void SetImage(Image image)
    {
        this.image = image;
        this.sha1 = ComputeSHA1(image);
    }

    private static string ComputeSHA1(Image image)
    {
        if (image != null)
        {
            var bytes = GetBytes(image);
            using (SHA1Managed SHA1 = new SHA1Managed())
            {
                return Convert.ToBase64String(SHA1.ComputeHash(bytes));
            }
        }
        else return string.Empty;
    }

    private static byte[] GetBytes(Image image)
    {
        using (var stream = new MemoryStream())
        {
            image.Save(stream, ImageFormat.Bmp);
            return stream.ToArray();
        }
    }
}

Using the above class, we can simply call the Equals method to find out if two images are equal in content, without ever having to worry about anything further other than creating ComparableImage objects.


The next issue is exposing a public Image property from each of the forms which enables us to access an instance of ComparableImage. We can easily accomplish this using the following pattern:

public class ComparableImageForm : Form
{
    // This is the property we need to expose:
    public ComparableImage Image
    {
        get { return this.image; }
        set { SetImage(value); }
    }

    private ComparableImage image;

    private PictureBox pictureBox = new PictureBox()
    {
        Dock = DockStyle.Fill
    };

    public ComparableImageForm()
    {
        this.Controls.Add(pictureBox);
    }

    // For clarity, we are also setting a picture box image
    // from the ComparableImage when it is assigned:
    private void SetImage(ComparableImage image)
    {
        this.image = image;
        pictureBox.Image = image.Image;
    }
}

Finally, we are ready to load some images do some test comparisons:

// Load two images from file to compare.
// In practice, images can be loaded from anywhere,
// even from the designer.
var image1 = new ComparableImage()
{
    Image = Image.FromFile("bitmap1.bmp")
};
var image2 = new ComparableImage()
{
    Image = Image.FromFile("bitmap2.bmp")
};


// Create two forms that have picture boxes:            
var formA = new ComparableImageForm()
{
    Image = image1
};
var formB = new ComparableImageForm()
{
    Image = image2
};

// Perform the check to see if they are equal:
if (formA.Image.Equals(formB.Image))
{
    MessageBox.Show("The images are indeed equal.");
}
else
{
    MessageBox.Show("The images are NOT equal.");
}


// Since images are compared based on their SHA1 hash, 
// it does not matter where the image comes from as long
// as the data is the same.  Here, we are loading another
// copy of 'bitmap1.bmp':
var anotherImage = new ComparableImage()
{
    Image = Image.FromFile("bitmap1.bmp")
};

// The following statement will evaluate as true:
bool isEqual = (anotherImage.Equals(image1));


Thats it!

Upvotes: 1

RomCoo
RomCoo

Reputation: 1893

It's not a good idea to compare images to detect if they are the same.

It would be better to give every picture an unique ID and store that in a variable. Make sure both forms haven access to that variable, so you can compare it with the ID of the image in form2.

Upvotes: 0

Vahid K.
Vahid K.

Reputation: 450

You should make an instance from your form B. search in controls of that form, find picturebox and change its properties. and show that instance everytime you want to show that form.

Upvotes: 0

Related Questions