Compare images to see if they're the same - c#

I'm trying to create a slot machine, i have 3 empty pictureboxes and a image list with a bunch of different pictures in it, i use a random number generator to put images into the picturebox from the image list.
Now how do i compare to see if the three random pictures are matching?
picturebox1.image == picturebox2.image;
//doesnt work because names aren't loaded to image property
picturebox1.imagelocation == picture2.imagelocation
//doesn't work because all images come from the same place.
I also can't try comparing the size or the extension because they are all the same
I don't want to use multiple random number generators to select the random pictures and compare the different random numbers. Is there a trick i can do with the imagelist that i haven't thought of

One option would be to use the Tag property... many classes have one, including Bitmap, Image, and PictureBox. You could assign a unique value to each Image.Tag...
var bmp = new Bitmap(1,1);
bmp.Tag = "uniqueTag";
pictureBox1.Image.Tag = bmp; // pictureBox1.Image.Tag == "uniqueTag"
... then check for equality:
if (pictureBox1.Image.Tag == pictureBox2.Image.Tag)
{
...
}

When your random generator picks the index of the element you will pull from your image list, store the index in the picturebox.Tag or picturebox.Text, then compare if both Tag o Text are equal.

Related

How to check on which page of a word document a shape/image is located using C# Interop

Using
var shapes = currentDocument.Shapes;
foreach (Shape shape in shapes)
if (shape.Type == MsoShapeType.msoPicture)
{
InlineShapeHelper.ReplaceInlineShape(...);
break;
}
I can replace the first image in "currentDocument".
How can I detect on which page the image is located (or in this case also sufficient: if it's on the first page)?
I want to replace an specific image on the first page, so is it maybe even possible to extract the image or check otherwise if the image is the one I'm looking for?
To answer your specific question: How can I detect on which page the image is located?
The get_Information method can return the page number of a given Range using the enumeration Word.WdInformation.wdActiveEndPageNumber.
A Shape is always anchored to a specific character in the document - this is the Range property of the Shape (Shape.Anchor).
The following code sample demonstrates how to loop the Shapes in a document, get their name and page number. Note that if the Shape.Name is known it's possible to pick up a Shape object directly (Shapes["Name As String"]). But you need to be careful with names generated by the Word application when Shape is inserted as Word can change the name it assigns itself at any time. If a name is assigned using code that name remains static - Word won't change it.
Word.ShapeRange shpRange = doc.Content.ShapeRange;
foreach (Word.Shape shp in shpRange)
{
System.Diagnostics.Debug.Print(shp.Name + ", " + shp.Anchor.get_Information(Word.WdInformation.wdActiveEndPageNumber).ToString());
}
One way I found just after posting the question is to generate the hash-code of the image:
var shapes = currentDocument.Shapes;
foreach (Shape shape in shapes)
if (shape.Type == MsoShapeType.msoPicture)
{
int hash = shape.GetHashCode();
InlineShapeHelper.ReplaceInlineShape(...);
break;
}
But I would still be interested in other, better, more elegant solutions and the possibility to get to know the page number.

C# assigning array element to another array

I am making a program which browses files, puts them into an array, and then the user puts those files in a random order into a new array called playlist.
To be clear I do not want to assign one array to the other array. I only want to assign one of the many elements of one array to another existing array.
How is this done?
Here is all I can think of:
playlist[1] = files[5];
You can utilize the System and System.IO namespace for all that fairly easily.
var files = Directory.GetFiles("directory path");
var playlist = new string[files.Length];
At that point, you'll have two arrays. The files array will contain the full path for every file in the directory you specified, and playlist will be a string array with the same size as the files array.
To get a random file and assign it to the playlist array, you can use the Random class in the System namespace to get a random number between a range.
var random = new Random();
int index = random.Next(0, playlist.Length);
You can use a bunch of logical statements to make sure that you don't copy over one file more than once, and that the space you're copying it to isn't already taken up by a file. But you had the idea idea. Transferring all the paths would look something like this
playlist[RandomPlaylistIndex] = files[RandomFileIndex];
with the lefthand side being the receiving end. That's pretty much the gist of it, anyhow. I can post more code if you're still stuck.
Use Array.Copy where you can define the Start and End of the source Array.
For instance, to copy the 15th element of Files to PLaylist:
Array.Copy(Files, 15, 1, Playlist, Playlist.Length,1)

Image comparison to Properties.Resources.image

Could you tell me why is the following condition false?
List<Image> SelectedImages = new List<Image>();
SelectedImages.Add(Properties.Resources.my_image);
if (SelectedImages[0] == Properties.Resources.my_image) // false
{
...
}
Even if I write:
SelectedImages[0] = Properties.Resources.my_image;
if (SelectedImages[0] == Properties.Resources.my_image) // false
{
...
}
How can I make this comparison work?
They're not equal because Properties.Resources makes a copy of the image and returns that copy back to your code. Everytime you get that image, you're effectively creating an entirely new Image object. It makes a copy because resources should ordinarily behave like constants. You wouldn't want your code to change the picture if you (for example) modified the picture in some way.
So what happens in your code? You end up comparing two different image objects that happen to contain the same data. .NET sees that you have two different objects and returns false. It doesn't do a "deep" comparision to see if the objects have the same data/state.
Here's a link to an article that explains what is going on at a high level: https://navaneethkn.wordpress.com/2009/10/15/understanding-equality-and-object-comparison-in-net-framework/
A quick way to workaround your problem would be to compare the Resource image and your SelectedImage Image pixel by pixel to see if they are "equal". This would obviously perform poorly. Another, more efficient way might be to build a dictionary and use a key to track where the image originally came from.
Just use the Tag property in the Image object. You can store anything you want in there. Just set up your image like this...
Image img_dbActive = MyApp.Properties.Resources.tray_icon_database_active;
img_dbActive.Tag = "tray_icon_database_active";
Image img_dbIdle = MyApp.Properties.Resources.tray_icon_database_idle;
img_dbIdle.Tag = "tray_icon_database_idle";
ToolStripStatusLabel lbl = new ToolStripStatusLabel("Database is doing something...", img_dbActive);
lbl.Image.Tag = "tray_icon_database_active";
if (lbl.Image.Tag == img_dbActive.Tag)
{
//Images match
}

Lookup the lowest index within an array that contains an object?

Hello I'm using the Microsoft.VisualBasic.PowerPacks Name space to create shapes on a windows form. I've used an array to store all the objects so that i can generate new shapes and modify the properties of a collection of objects, dependent on given scenarios.
I'm attempting to perform a look-up on the array an find the lowest index that contains an Oval Shape. After trawling the internet for quite some time, I've only found statements that will accept fixed values, since every location within the array contains the same value I can't do that.
I'm looking for something along the lines of the statement below. Where i can find either the first entry that is not null or contains an "Microsoft.VisualBasic.Powerpacks.Ovalshape" the object not the type. Thanks.
// ** Object declaration
Microsoft.VisualBasic.PowerPacks.OvalShape shape = new Microsoft.VisualBasic.PowerPacks.OvalShape();
Microsoft.VisualBasic.PowerPacks.OvalShape[] shapes;
**//
int myIndex = Array.IndexOf(shapes, != null);
Simply use:
Array.FindIndex(shapes, s => s != null)

choosing items based on random numbers

I am working on a small game where prizes are awarded based on a random number. So when a mission is completed and the reward has to be handed out, I want to randomly generate the prize. Currently I am getting a random number between 1 and 500 and then using a giant nested if-else statement to assign the prize based on the result. It is obvious to me that this is the wrong way to do this, however I am not sure what other way this may be done.
Any suggestions?
You can just use a prize array to hold your prices, use the random value as index into the array to pick a prize.
var prizes = new Prize[500];
//fill prizes
//randomly select index within prize array
If there are gaps or only a few numbers win anything, use a dictionary mapping from an integer to a prize ( or nothing if they key doesn't exist) instead.
There are many things you could do. For example, you could use an array to store the prizes and use the random number as the index of the array. The prize would then be whatever was stored in the array at that index. You could do the same with a List if you wanted more control.
Use a list where each item has a unique "minimum value" and information about the associated prize. Then find the item on the list that has the highest value, but is still below your random number. Or vice-versa.
The minimum value allows you to give different probabilities to prizes without using a giant array that has an entry for all numbers. The probabilities are defined by the distances of the values between different prizes.
In this example I assume that your prizes are strings (but this works with objects too).
Create a list and add all of your prizes to it, in the following way:
//using System.Collections.Generic;
var prices = new List<string>();
//Add all of your prices here
var random = new Random();
var price = prices[random.Next(0,prices.Count)];

Categories