Durga
Durga

Reputation: 1303

Displaying Images randomly from folder in multiple picture boxes

I am using this code for displaying Images from Image folder randomly in 3 picture boxes with some intervals, but in ARandomNumber I am getting System.drawing.Bitmap and because of this I am getting FileNotFoundException since I am geting this path in pictureBox3.image C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\System.Drawing.Bitmap.png

I am not understanding where I am going wrong:

namespace StudentModule
{
    public partial class Form1 : Form
    {
        Random r = new Random();
        int index = -1;
        List<Image> images;
        Image ARandomNumber;
        Timer timer = new Timer();
        private int counter = 0; 
        public Form1()
        {
            InitializeComponent();
            timer1.Interval = 350;
            timer1.Tick += new EventHandler(timer1_Tick);

            List<Image> images = new List<Image>();//add images to this array
            DirectoryInfo di = new DirectoryInfo(@"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image"); // give path
            FileInfo[] finfos = di.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);
            foreach (FileInfo fi in finfos)
                images.Add(Image.FromFile(fi.FullName));
            index++;
            if (index < 0 || index >= images.Count)
                index = 0;
            timer.Start();
            pictureBox1.Visible = false;
            pictureBox2.Visible = false;
            pictureBox3.Visible = false;
            pictureBox4.Visible = false;


            int indx = r.Next(0, images.Count - 1);

            ARandomNumber = images[index];
            images.RemoveAt(indx);

            string path = @"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\";
            pictureBox3.Image = Image.FromFile(path + ARandomNumber + ".png");
            indx = r.Next(0, images.Count - 1);

            ARandomNumber = images[index];
            images.RemoveAt(index);
            pictureBox4.Image = Image.FromFile(path + ARandomNumber + ".png");
            indx = r.Next(0, images.Count - 1);
            ARandomNumber = images[index];
            images.RemoveAt(index);
            pictureBox5.Image = Image.FromFile(path + ARandomNumber + ".png");
            //Console.WriteLine(ARandomNumber);
            if (images.Count <= 1)
            {
                images.Clear();
                populateImag();
            }
        }
        public void timer1_Tick(object sender, EventArgs e)    
        {
           counter++;
           if (counter == 1) 
            //or whatever amount of time you want it to be invisible            
        {
            pictureBox3.Visible = true;

        }
        if (counter == 2)
        {
            pictureBox4.Visible = true;
        }
        if (counter == 3)
        {
            pictureBox5.Visible = true;
            timer.Stop();
            counter = 0;
        }                     
       }
        public void populateImag()
        {
            List<Image> images = new List<Image>();//add images to this array
            DirectoryInfo di = new DirectoryInfo(@"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image"); // give path
            FileInfo[] finfos = di.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);
            foreach (FileInfo fi in finfos)
                images.Add(Image.FromFile(fi.FullName));
        }
    }
}

Thank in advance for any help.

Upvotes: 0

Views: 3127

Answers (3)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236218

Add timer in designer, set it's interval and subscribe to it's Tick event in designer - that will make your code cleaner. Next - create list of picture boxes, which you want to use for showing random images:

public partial class Form1 : Form
{
    Random random = new Random();
    List<string> filesToShow = new List<string>();
    List<PictureBox> pictureBoxes;

    public Form1()
    {
        InitializeComponent();

        pictureBoxes = new List<PictureBox> {
            pictureBox1,
            pictureBox2,
            pictureBox3
        };

        ShowRandomImages();
        timer1.Start();
   }
}

The only method called from constructor is ShowRandomImages here its definition:

private void ShowRandomImages()
{
    foreach (var pictureBox in pictureBoxes)
    {
        if (!filesToShow.Any())
            filesToShow = GetFilesToShow();

        int index = random.Next(0, filesToShow.Count);
        string fileToShow = filesToShow[index];
        pictureBox.ImageLocation = fileToShow;
        filesToShow.RemoveAt(index);
    }
}

This method assign random image from location. If there is no files to show left, then list is re-loaded. Keep in mind - if you need only file names, then use Directory instead of DirectoryInfo and FileInfo:

private List<string> GetFilesToShow()
{
    string path = @"C:\some\folder";
    return Directory.GetFiles(path, "*.jpg", SearchOption.TopDirectoryOnly)
                    .ToList();
}

All you need to do - call ShowRandomImages method from timer tick event handler.

Upvotes: 0

Recipe
Recipe

Reputation: 1406

ARandomNumber is an image, it is not a Path. An image is a resource loaded into memory and is not always linked to a path.

This isn't going to work, because ARandomNumber.ToString() is not returning a path (I suggest using as string containing the filepath instead of ARandomNumber):

pictureBox3.Image = Image.FromFile(path + ARandomNumber + ".png");

Second, you first load all *.jpgs:

FileInfo[] finfos = di.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);

Then, you load an image that has the extension of *.png:

pictureBox3.Image = Image.FromFile(path + ARandomNumber + ".png");

Are you sure there is both a jpg and png image with the same name in your folder?

Edit: Possible solution would be to load the file path as string instead of loading the images OR (because you have all of your images in an array), try this:

ARandomNumber = images[index]; //Here you take a random image from the array of images
images.RemoveAt(indx);

pictureBox3.Image = ARandomNumber; //Here you assign the image directly to the Image property in picturebox. You do not need to load it again from file.

Upvotes: 2

Akshay
Akshay

Reputation: 1901

While selecting image files you are selecting ".jpg" images and while loading you are you attaching ".png" extension to these file. I think this is causing trouble. Look at error :

pictureBox3.image C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\System.Drawing.Bitmap.png

File name having 2 extensions. .Bitmap.png

Upvotes: 0

Related Questions