Перемешать случайное изображение из ресурсов при нажатии кнопки

У меня есть 1 ящик с картинками, названный studPic. Я хочу получить, когда я нажимаю кнопку перемешивания, чтобы получить случайное изображение из ресурсов.

private void button2_Click(object sender, EventArgs e)
        {
...     
        }

После исследования я обнаружил следующее

http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvcs/thread/38d36fa4-1f5f-43e9-80f6-3c9a4edc7705/

Я новичок в С#. Есть ли более простой способ добиться этого результата? Например, без добавления имен картинок?

ОБНОВИТЬ

List<string> pictureNames = new List<string>();
pictureNames.Add("1");
pictureNames.Add("2");
pictureNames.Add("3");
int randomPictureIndex = new Random().Next(0, pictureNames.Count);
string randomPictureName = pictureNames[randomPictureIndex];
pictureNames.Remove(randomPictureName);
Image img = Properties.Resources.randomPictureName; //erroor
studPic.Image = img;

получение сообщения об ошибке Ошибка 1 «Properties.Resources» не содержит определения для «randomPictureName»


person heron    schedule 03.07.2012    source источник
comment
Ресурсы приложения @ChrisGessler   -  person heron    schedule 04.07.2012
comment
@ChrisGessler обновлен. пожалуйста, взгляните   -  person heron    schedule 04.07.2012
comment
Это ищет ресурс с именем randompicturename, а не тот, который хранится в переменной randompicturename. Посмотрите на класс ResourceManager. Немного повозившись, вы бы использовали MyResourceManager.GetObject(randompicturename)   -  person Tony Hopkinson    schedule 04.07.2012


Ответы (3)


Я бы не стал использовать системные ресурсы для этого. Они не так просты в сопровождении, как файловая система для автономного программного обеспечения.

Поместите изображения в папку для вашего приложения. Таким образом, они могут быть легко обновлены/изменены. Сказать :

C:\Ninjas - app
c:\Ninjas\images - images

Создайте массив, содержащий эти изображения.

string[] files = System.IO.Directory.GetFiles("c:\ninjas\images");

Вам нужно будет поместить некоторые фильтры в GetFiles, чтобы убедиться, что вы получаете только изображения.

Теперь возьмите случайную позицию в этом массиве (вы уже показали, что знаете, как делать случайные числа).

У нас есть массив, давайте перемешаем его, а затем вы можете просмотреть их последовательно (намного быстрее, чем случайным образом выбирать. CPU будет любить вас за это)

    private string[] files;
    private int currentIndex = 0;

    private void initializeImages()
    {
        //Grab directories in your images directory
        string appRoot = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
        files = System.IO.Directory.GetFiles(appRoot + @"\images");
        Random rnd = new Random();
        files = files.OrderBy(x => rnd.Next()).ToArray();
    }


    private void setImage()
    {
        pictureBox1.ImageLocation = files[currentIndex];
    }

    private void previousImage()
    {
        currentIndex = currentIndex > 0 ? currentIndex - 1 : 0;
        setImage();
    }

    private void nextImage()
    {
        currentIndex = currentIndex < files.Length - 1 ? currentIndex + 1 : files.Length - 1;
        setImage();
    }

Пара вещей:

  • Не жестко кодируйте путь к файлу. Имейте это в своем файле app.config и ссылайтесь на него.
  • Вы можете сделать файловый массив глобальным, чтобы его не нужно было запускать каждый раз.

Если вы хотите, чтобы это было слайд-шоу, которое будет работать до тех пор, пока пользователь не отменит его, я бы рекомендовал следующее:

  • Используйте объект таймера, который вызывает метод для увеличения количества изображений, что меняет изображение.
  • Не используйте thread.sleep в своем графическом интерфейсе, так как он приостановит работу вашего графического интерфейса - а это нехорошо.

Если вы хотите добавить кнопки Next/Previous, вам понадобится глобальный индекс (скажем, currentIndex), который можно увеличить/уменьшить, а затем вызвать код для установки изображения

person Ryan Ternier    schedule 03.07.2012

С вашей стороны требуется некоторая настройка, но скептики в основном правы. Это не очень правильное решение для производственного приложения. При этом я сомневаюсь, что это то, что вы распространяете среди множества людей, поэтому мы назовем это академическим упражнением. Если бы вы просто добавили ресурс в свое приложение и назвали его «ImageResource» (подойдет любое имя) и добавили к нему свои изображения, вы можете использовать следующий код (при условии, что соответствующие элементы пользовательского интерфейса существуют).

Во-первых, мы создаем функцию для извлечения растровых изображений из вашего ресурса.

private Bitmap[] GetResourceImages()
{
    PropertyInfo[] props = typeof(ImageResource).GetProperties(BindingFlags.NonPublic | BindingFlags.Static);
    var images = props.Where(prop => prop.PropertyType == typeof(Bitmap)).Select(prop => prop.GetValue(null, null) as Bitmap).ToArray();

    return images;
}

Во-вторых, мы создаем функцию, которая рандомизирует изображение на основе доступных изображений:

private void RandomizePicture()
{
    Bitmap[] images = GetResourceImages();
    if (images == null || images.Length == 0)
    {
        //Nothing to do here...
        return;
    }

    int maxValue = images.Length;
    Random r = new Random();
    int idx = r.Next(maxValue);
    this.uxStupidPic.Image = images[idx];
}

Наконец, вызовите эту функцию по нажатию кнопки:

private void btnRandmoize_Click(object sender, EventArgs e)
{
    this.RandomizePicture();
}

И вуаля, рандомизированные изображения из файлов ресурсов. Удачного кодирования!

РЕДАКТИРОВАТЬ: только что заметил, что вы сказали, что используете ресурс приложения, а не случайный файл ресурса. Просто замените «ImageResource» на «Properties.Resources» в GetResourceImages, и вы будете в деле.

person Jaime Torres    schedule 03.07.2012

Мне нравится ответ Райана Тернье, очень простой и элегантный, я собирался опубликовать решение, похожее на его.

Я просто хочу прокомментировать причины, по которым линия не работает/не должна работать:

Изображение img = Свойства.Ресурсы.randomPictureName;

  1. Это связано с тем, что ресурсы свойств ищут ресурс с именем «randomPictureName», а не само фактическое имя.
  2. Объект Properties.Resources работает таким образом, что он ищет все ваши ресурсы в свойствах вашего решения во время выполнения после компиляции кода. Это не будет работать так, как вы хотите, поскольку вы пытаетесь передать статическую переменную, которая может даже не существовать в ресурсах, что вынуждает вас на всякий случай обернуть свой метод вокруг оператора try/catch.

http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx

person sksallaj    schedule 04.07.2012