C # отображать изображения в случайном порядке и один за другим - PullRequest
3 голосов
/ 10 января 2011

Я создаю простую систему отображения сообщений на основе форм, каждое сообщение представляет собой изображение в формате JPEG, чего я хочу добиться, когда программа загружает (сразу после того, как пользователь вошел в систему) один из файлов jpg, выбранный случайным образом и показанный,если пользователь нажимает кнопку «Далее», отображается другой файл JPG, пока все не будут отображены.Я думаю, что мне нужно прочитать каждое изображение в массив, а затем случайным образом выбрать одно из массива, а затем, когда пользователь нажимает кнопку Далее, перейти к следующему элементу в массиве.Одно предупреждение: я не хочу, чтобы программа открывала файлы jpg, поскольку другие должны иметь возможность их удалять.

Мой текущий код приведен ниже, я был бы признателен за любую помощь и совет, который вы можете предложить.

private void Form1_Load(object sender, EventArgs e)
 {
      var rand = new Random();
      var files = Directory.GetFiles(@"\\server\screens\", "*.jpg");
      pictureBox1.Image = System.Drawing.Bitmap.FromFile(files[rand.Next(files.Length)]);  
 }

private void buttonNextImage_Click(object sender, EventArgs e)
 {
      var rand = new Random();
      var files = Directory.GetFiles(@"\\server\screens\", "*.jpg");
      pictureBox1.Image = System.Drawing.Bitmap.FromFile(files[rand.Next(files.Length)]);
 }

Большое спасибо Стивен

Ответы [ 7 ]

3 голосов
/ 10 января 2011

Не используйте Bitmap.FromFile, используйте Bitmap.FromStream:

using(var fs = new FileStream(files[rand.Next(files.Length),
                              FileMode.Open, FileAccess.Read))
{
    pictureBox1.Image = System.Drawing.Bitmap.FromStream(fs);
}

Не знаю, как создать массив изображений

var files = Directory.GetFiles("\\\\server\\screens\\", "*.jpg");
var images = new Image[files.Length];
for(int i = 0; i < files.Length; ++i)
{
    using(var fs = new FileStream(files[i], FileMode.Open, FileAccess.Read))
    {
        images[i] = System.Drawing.Image.FromStream(fs);
    }
}
2 голосов
/ 10 января 2011

Здесь есть две вещи:

  1. Переместите ваш случайный экземпляр в класс, чтобы его можно было создать только один раз.массив файлов, так что в списке остаются только те изображения, которые вы не показали.Когда список пуст, вы знаете, что показали их все.
0 голосов
/ 30 декабря 2012
public static int id = 0;
private void timer1_Tick(object sender, EventArgs e)
{
    id = id + 1;
    filelocation = "E:\\example\\" + id + ".bmp";
    pictureBox1.Image = System.Drawing.Bitmap.FromFile(filelocation);
}
0 голосов
/ 10 января 2011

Вот общий способ выполнения вашего запроса.

  1. Загрузите все файлы jpeg в выбранном каталоге (из вашего примера, \\Server\Screens\) в массив.

  2. Рандомизировать массив файлов.Вот пример реализации перетасовки массива: Наиболее эффективный способ случайного перемешивания списка целых чисел

  3. Загрузка первого изображения в массив.Массив, очевидно, содержит имена файлов, поэтому вы не можете просто указать свойство Image PictureBox на нужный элемент;вам придется загрузить изображение.

    Поскольку вы не хотите блокировать изображения, рекомендуется загружать изображения из потока (см. @ max's answer ).

  4. Когда пользователь нажимает на следующую кнопку, загружает следующее изображение.Вам придется проверить, существует ли файл, так как из вашего вопроса, я полагаю, пользователь может удалить файл до его загрузки.

0 голосов
/ 10 января 2011

Список советов:

  • Не делайте массив картинок;сделайте HashSet<string> имен файлов, которые вы уже показали.Затем, когда нажата NEXT , повторите итерацию в папке еще раз и проигнорируйте имена файлов, которые вы уже показали.Из того, что осталось (если есть), выберите один наугад.Таким образом, даже если содержимое папки изменится во время выполнения, вы все равно получите большую ее часть.И вы не потеряете память, загружая все изображения одновременно.
  • Когда пришло время отобразить изображение, загрузите его, как вы, затем Clone(), а затем Dispose() оригинал.Таким образом, он не блокирует файл.
  • При отображении следующего изображения не забудьте Dispose() предыдущее, чтобы освободить ресурсы.
0 голосов
/ 10 января 2011

Я считаю, что у вас есть 2 варианта:

a) Вы загружаете файлы JPG в потоки памяти (наихудший вариант).

b) Вы создаете временные файлы с тем же именем и суффиксом, как «tmp» (т. Е. «1.tmp.jpg»).

Непосредственно взяв «b», после создания копий вы сделаете индекс тех файлов, которые вы хотите показывать случайным образом на уровне класса.

После этого используется какой-то таймер для изменения изображения после каждого тика.

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

Это мое предложение :)

0 голосов
/ 10 января 2011

Расширяя ответ Ойвинда Бротена, вы можете сбросить массив после того, как все снимки будут показаны, а также, возможно, вы можете использовать таймер, который очень часто автоматически меняет изображение?

...