C#で指定したフォルダから画像を読み込んでスライドショーを作る方法

このQ&Aのポイント
  • C#を使って、指定したフォルダから画像を読み込み、スライドショーとして表示する方法を教えてください。
  • 現在のコードでは、最後の画像しか表示されないため、連続して画像を表示する方法を知りたいです。
  • スライドショーを作りたいので、どのように修正すればいいか、具体的な方法を教えてください。
回答を見る
  • ベストアンサー

C#を勉強していて、指定したフォルダから画像を読み込んでピクチャボック

C#を勉強していて、指定したフォルダから画像を読み込んでピクチャボックスに次々と表示するスライドショーを作っています。 それで次のように作りました。 string[] files = System.IO.Directory.GetFiles(@"c:\test\", "*.jpg");  foreach (string file in files)  {   pictureBox1.Image = Bitmap.FromFile(file);   this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; Thread.Sleep(1000);  } しかしこれではフォルダの最後の画像しか表示されません。 この場合次々と画像を表示するにはどうしたらいいか教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

using System; namespace Q5582265 { class Q5582265:System.Windows.Forms.Form { private System.Windows.Forms.PictureBox picturebox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; /* System.Windows.Forms.Timerの方が好きな人いるかも */ private System.Timers.Timer timer1; private System.Windows.Forms.TextBox textbox1; private System.Collections.Generic.List<System.IO.FileInfo> ImagefileInfos; Q5582265(){ this.Width = 800; this.Height = 600; textbox1 = new System.Windows.Forms.TextBox(); textbox1.Top = 0; textbox1.Left = 0; textbox1.Width = 800; button1 = new System.Windows.Forms.Button(); button1.Top = 50 - 20; button1.Left = 0; button1.Width = 200; button1.Enabled = true; button1.Text = "Start"; button1.Click += this.button1_Click; button2 = new System.Windows.Forms.Button(); button2.Top = 100 - 20; button2.Left = 0; button2.Width = 200; button2.Enabled = false; button2.Text = "Stop"; button2.Click += this.button2_Click; picturebox1 = new System.Windows.Forms.PictureBox(); picturebox1.Top = 100; picturebox1.Left = 0; picturebox1.Width = 800; picturebox1.Height = 500; picturebox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.Controls.Add(textbox1); this.Controls.Add(button1); this.Controls.Add(button2); this.Controls.Add(picturebox1); timer1 = new System.Timers.Timer(1000); timer1.Enabled = false; timer1.Elapsed += this.timer1_tick; } private void button1_Click(object sender,System.EventArgs e){ System.Collections.Generic.List<System.IO.FileInfo> fileInfos = new System.Collections.Generic.List<System.IO.FileInfo>(new System.IO.DirectoryInfo(textbox1.Text).GetFiles()); /* 画像だけが含まれるかどうかわからないので */ fileInfos = fileInfos.FindAll(delegate(System.IO.FileInfo fi){ bool isImage = false; try{ new System.Drawing.Bitmap(fi.FullName); isImage = true; }catch(Exception){ isImage = false; } return isImage; } ); /* 俺の書き方の都合上、0個の場合は避けておきたいのだ */ if (fileInfos.Count > 0){ this.ImagefileInfos = fileInfos; button1.Enabled = false; button2.Enabled = true; textbox1.Enabled = false; timer1.Enabled = true; }else{ this.ImagefileInfos = null; } } private void button2_Click(object sender,System.EventArgs e){ button1.Enabled = true; button2.Enabled = false; textbox1.Enabled = true; timer1.Enabled = false; } private void timer1_tick(object source, System.Timers.ElapsedEventArgs e){ picturebox1.Image = new System.Drawing.Bitmap(ImagefileInfos[0].FullName); /*この辺の書き方は俺の書き方の好みがモロに出てる */ ImagefileInfos.Add(ImagefileInfos[0]); ImagefileInfos.RemoveAt(0); } public static void Main(String[] args){ Q5582265 form1 = new Q5582265(); form1.ShowDialog(); } } } /* フォルダ名が正しくなかった時の処理はしてない。 実際にはテキストボックスへの直接入力を認めず、 OpenFileDialogでも置いた方がいいかと。 Windows APIには頼りたくないな。 俺のやり方だと、yieldっぽいのなくて、ファイル名全てを取得して帰ってくるまで待たされる欠点はあるけど。>#1 */

real1130
質問者

お礼

細かくわかりやすい説明ありがとうございます。

その他の回答 (1)

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

FileFindFirstとFileFindNext使うのでは駄目?

real1130
質問者

お礼

アドバイスありがとうございます。 参考にしてみます。

関連するQ&A

  • ピクチャーボックスの大きさに合わせて画像を表示

    縦に長い画像をピクチャーボックスに表示したいのですが、 エクスプローラーの縮小表示と同じように 縦長の場合は左右に余白が出来て、画像の縦横比は 変更しないですべてを表示したいのですが、 どのようにしたら良いでしょうか。 PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage を使うと全部入るのですが、左右に余白がないように 引き伸ばしてしまうので、何の画像なのか分かりにくくなってしまいます。 よろしくおねがいします。m(__)m

  • C# 画像ファイルの更新

    C#を始めて2ヶ月余りの者です。 環境はW.7 C#.NET 2013です。 現在、以前C-Builderで作成したプログラムをC#に変換して居ます。 画像マスターを変更する所で、コンパイル出来なく成り、困って居ます。 やりたい事は、画像マスターがあり、これを表示して、マスターを変更したければカメラから読み込んだ画像を画像マスターに書き込むと言うものです。 C-Builderの時はBMPの読み書きは自分で作成しましたが、C#では関数があるので今回はこれを利用しました。 内容を簡略的に下に記述しました。AAAが画像マスターでBBBがカメラからの画像の代わりです。 ここで bmpSource1.Save(sCurDir + "\\BBB.bmp"); を実行すると、「別のプロセスで使用されているため、プロセスは ファイル~にアクセスできません。」とのエラーが表示されます。 良く考えてみれば、Readでオープンしている所に書き込もうとして居るのでエラーに成って当たり前ですので、bmpSource1 = new Bitmap(sCurDir + "\\AAA.bmp");の後に画像を別の場所に保存し、bmpSource1.Dispose();としてみた所、上手く行きませんでした。これもDisposeするのはバッファーであり、ファイルでは無いから当たり前かも知れません。 ネットで色々探して居る時に、何かのパラメーターでReadWriteモードの所を見つけましたが、bmpSource1 = new Bitmap(sCurDir + "\\AAA.bmp");には指定するパラメーターが見当たりませんでした。 何方か、画像ファイルの更新方法がお分かりに成る方、ご教授下さい。 よろしくお願い致します。 String sCurDir = System.IO.Directory.GetCurrentDirectory(); Bitmap bmpSource1; Bitmap bmpSource2; public Form1() { InitializeComponent(); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; bmpSource1 = new Bitmap(sCurDir + "\\AAA.bmp"); bmpSource2 = new Bitmap(sCurDir + "\\BBB.bmp"); pictureBox1.Image = bmpSource1; bmpSource2.Save(sCurDir + "\\AAA.bmp"); <-ここで実行時エラー }

  • visual C++でのツール番号の指定方法

    Visual C++では、pictureBoxやtextBoxなどのツールがありますが、例えば、以下のようにpictureBoxの番号にあったファイルを表示する場合にはどのように書き込めばいいでしょうか? pictureBox1→1.bmpを開く pictureBox2→2.bmpを開く ・・・ pictureBoxn→n.bmpを開く nの数が少なければ、 pictureBox1->Image=Image::FromFile("C:/Users/1.bmp"); のように書いていけばいいですが、nの数が多くなれば、その分書き込まなければならないですし、 この番号をプログラム内でfor文などで指定できるようにするにはどのように書き込めばいいでしょうか?

  • C# Gifアニメーション画像の読込みと表示???

    FormでGIFアニメーション画像を読込み、pictureBoxに表示します (1)の方法では思った通りに表示されます Bitmap GifImage1 = new Bitmap(100, 100); ・・・・・ (1) GifImage1 = new Bitmap(@"f:\TestPattern.gif"); pictureBox1.Image = GifImage1; しかし(2)の方法ではFormをロードするProgram.csでエラーを起こしてしまします Bitmap GifImage2 = new Bitmap(100, 100); ・・・・・ (2) FileStream ImageStream = new FileStream(@"f:\TestPattern.gif", FileMode.Open, FileAccess.Read); GifImage2 = (Bitmap)System.Drawing.Bitmap.FromStream(ImageStream); ImageStream.Close(); pictureBox2.Image = GifImage2; (1)の方法ではファイルがロックされると聞いておりますので、通常は(2)を使用しています またTestPattern.gifがアニメーション画像ではなく単なるGif画像の際は(1)(2)双方ともOKです この辺りの理由をボンクラの私にも分かるように教えてください お願い致します

  • C# PictureBoxで使用した元画像を削除できない

    現在PictureBoxに表示させた画像を、PictureBoxを定義しているFormを閉じた瞬間削除しようと考えています。 例) メインFormからPictureBoxを定義しているSubFormを表示します。 PictureBoxに、ローカルマシンにある任意のファイルをImageとして表示させます。 pictureBox1.Image = Image.FromFile(@"C:xxx.jpg"); このFormを閉じた後、PictureBoxで表示していたファイルを削除したいのですが、「他のユーザが使用しているため、削除できません」というエラーが発生して削除が実行できません。 ガベージが実行されていないからか?と考え、Formを閉じるときに以下の処理を行いました。 pictureBox1.Image = null; pictureBox1.Dispose(); それでも結果は変わりませんでした。 メインFormからサブFormとして行った場合のみ、本現象が発生します。 メインFormが閉じられれば、その直後からファイル削除を実行できます。 どうか、よろしくお願いいたします。

  • C++/CLIでの画像情報(RGB)の取得

    Visual C++ 2005のC++/CLI対応で、.NET Frameworkのクラスライブラリを使用し、画像処理のプログラムを作成しています。 pictureBox1->Image = gcnew Bitmap( ファイル名 ); で、画像を表示するところまではできたのですが、表示したBitmapデータのRGBカラー情報を取得する方法がわからず、困っています。 ご存知の方、教えてください。 また、このような情報が載っている書籍やサイトがありましたら、合わせて教えてください。 よろしくお願いします。 必要な情報が抜けていましたら、お手数ですが、ご指摘お願いします。

  • C#でピクチャーボックスに文字を描画、出力する方法

    以下のことをやりたいのですが、できなくて困っています。 Microsoft Visual Studio 2010 Expressを使っています。 1、ピクチャーボックスに色画像を表示 2、ピクチャーボックスに文字(説明)も表示 3、その画像を出力 2まではできたのですが、2までできたあとに、プログラムのウインドウ上に他のウインドウ(マイコンピュータやマイドキュメントなど)が表示されたり、プログラムのウインドウを最小化したりして、一度隠れてしまうと文字が消えてしまうようで、画像のみの出力になってしまいました。(画像のみの出力には成功しています) なんとかして出力する方法はないでしょうか。 以下がソースです。よろしくお願いします。 ボタン1 Bitmap bmp6 = new Bitmap(800, 600); int sr, sg, sb, i, j; sr = 100; sg = 100; sb = 100; for (i = 0; i < 40; i++) { for (j = 0; j < 40; j++) { bmp6.SetPixel(i, j, Color.FromArgb(sr, sg, sb)); } pictureBox1.Image = bmp6; } ボタン2 string s1 = "文字"; Font newfont = new Font("MS明朝", 10); pictureBox1.CreateGraphics().DrawString(s1, newfont, Brushes.Blue, 50, 200); ボタン3 pictureBox1.DrawToBitmap(bmp, new Rectangle(0, 0, 800, 600)); bmp.Save(c:\\a.png);

  • C#にて、イメージ画像の分割

    C#言語にて現在パズルゲームを作成しようと考えています。 パズルに使用するピースですが、ユーザが任意に選択した画像をプログラミングで規定の画像サイズに切り出し、それをパズルピースとして使用する仕様を考えています。 ファイルを開くボタン押下で、OpenFileDialogを表示し、ユーザに任意のイメージ画像を選択させます。その選択された画像を58pixcelx58pixcelのサイズの画像を9x6の54枚(パズルピース)に分割します。 以下がその仕様を考えたソースコードです。 private void selectButton_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); if (openFileDialog.ShowDialog() == DialogResult.OK) imageShow(openFileDialog.FileName); } private void imageShow(string filePath) { Bitmap _bmp = new Bitmap(58, 58); Image originalImage = Image.FromFile(filePath); Graphics g = Graphics.FromImage(_bmp); Rectangle rect; int x = 0; int y = 0; string title = "C:\\Image"; int index = 0; for (x = 0; x < 9; x++) { for (y = 0; y < 6; y++) { index++; rect = new Rectangle((x * 58) , (58 * y), 58, 58); g.DrawImage(originalImage, 0, 0, rect, GraphicsUnit.Pixel); _bmp.Save(title + index.ToString()+ ".jpg",System.Drawing.Imaging.ImageFormat.Jpeg); Thread.Sleep(50); } y = 0; } } パズルピースとして使用する予定のサイズ58x58のBitmapを作成します。そのBitmapからGraphicsを作成し、Graphicsに対してDrawImageでオリジナル画像(ユーザが選択した画像)を58Pixcelごとに分割し、分割されて作成されたImageをSave()にてファイル保存しています。 この仕様で一応ファイルは分割されて作成されるのですが、どうも画像の位置が合わないのです。画質も悪いですし。手動で同じオリジナルファイルを58Pixcelごとに切り出したものと比較しますと顕著にちがいます。 何か足りない処理や、他の対応策がございましたらご教授のほどよろしくお願いいたします。今回の仕様で、切り出したファイルをローカルマシンに保存する、と言うのは必須事項になっております。 どうか皆様よろしくお願いいたします。

  • c#のメソッドjoinが機能しない

    Microsoft visual C#2005でスレッドを使用したプログラムを行なっているのですが,意図した動作を行えません. 意図する動作は,連番で複数の画像を持つ二つのフォルダ(0,1とします)から画像をリストに読み込み,フォルダ0読み込み→フォルダ0内の画像を順に続けて表示(この間にフォルダ1の読み込み)→3秒置いて→フォルダ1内の画像を順に続けて表示です.     //再生ボタン private void button_Click(object sender, EventArgs e) {       //フォルダ0読込 directory = directories[0]; Read = new Thread(new ThreadStart(read_image)); Read.Start(); if(now_loading == true) { Read.join(); } //フォルダ0表示 Showing1 = new Thread(new ThreadStart(Show)); Showing1.Start(); //フォルダ1読込 directory = directories[1]; Reads = new Thread(new ThreadStart(read_images)); Reads.Start(); }       if(now_showing == true) { Showing1.Join(); } if(now_showing == true) { Reads.Join(); } //フォルダ1表示 Showing2 = new Thread(new ThreadStart(Show)); Showing2.Start(); }     //動画表示 private void Show() { Stopwatch sw = new Stopwatch(); //リストに入っているファイルの数をfile_numbersに入れる file_numbers = img.Count; //1枚目を表示 pictureBox1.Image = img[0]; //フレーム番号のリセット now_show = 1; //時間計測:開始 sw.Start(); while (now_show < file_numbers) { if (33 <= sw.ElapsedMilliseconds)//一枚の表示時間が33ミリ秒以上になったら次の画像を表示 { //前フレームを消去 img[0].Dispose(); img.RemoveAt(0); //画像を表示 pictureBox1.Image = img[0]; //カウントを進める now_show++; //時間計測再スタート sw.Reset(); sw.Start(); } } //時間計測:停止 sw.Stop(); //最終フレームを消去 pictureBox1.Image = null; img[0].Dispose(); img.RemoveAt(0); Thread.Sleep(3000);//3秒待機 } //読込 private void read_images() { int read_numbers = Directory.GetFiles(directory).Length; now_loading = true; for (int i = 0; i < read_numbers; i++) { img.Add(Image.FromFile(String.Format("{0}\\{1:000}.jpg", directory, i))); } now_loading = false; } //初回読込 private void read_image() { now_loading = true; //フォルダ内のファイル数の取得 file_numbers = Directory.GetFiles(directory).Length; //画像ファイルを読み込む img = new List<Image>(); for (int i = 0; i < file_numbers; i++)//ファイル数の数 { img.Add(Image.FromFile(String.Format("{0}\\{1:000}.jpg", directory, i))); } now_loading = false; } joinでスレッドの終了を待つということなので,B表示スレッドを開始する前に A表示スレッド.join を置けばよいと考えたのですが,タイマーを配置して見たところA表示のスレッドのjoinを待つ前にB表示のスレッドが始まってしまっているようです.(Show内の始めと終わりの部分でテキスト表示すると,フォルダ1の再生後にフォルダ0のShowスレッドが終了していました) また,各画像フォルダの再生時間もタイマで図るとほぼ指定した通りなのですが自分の時計で計測すると画像500枚で2秒程度短くなってしまいます. joinを使っている時点で表示スレッドを関数にした方が良いのかもしれませんが,何故思うように動かないのか知りたいです. アドバイス頂けると嬉しいです.

  • C#)フォルダを参照したい

    こんにちわ。 フォルダを参照してその中身をリストBOXに表示したいのですが、サンプルを見つけて実行したのですがいまいち理解できなかったのでアドバイスくださると助かります。 private void button1_Click(object sender, System.EventArgs e) { string systemFolder = Environment.GetFolderPath    (Environment.SpecialFolder.System); DirectoryInfo di = new DirectoryInfo(systemFolder); foreach(FileInfo fi in di.GetFiles()) { listBox1.Items.Add(fi.Name); } } これでボタン1をクリックするとsystemフォルダの内容がリストに表示されるのですが、そもそもどこのsystemフォルダなのか分かりません・・・。 ↑のプログラムが分からず別の方法でまずフォルダ参照ダイアログの FolderBrowserDialog を使おうと思ったのですが、ツールBOXに無いのでまた困りました。 どなたか分かる方いたらご指摘お願いします。