3

という名前の 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/

私はC#の初心者です..この結果を達成する簡単な方法はありますか? たとえば、写真の名前を追加せずに?

アップデート

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' の定義が含まれていません

4

3 に答える 3

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 ファイルに入れ、参照します。
  • 毎回実行する必要がないように、ファイル配列をグローバルに配置できます。

これをユーザーがキャンセルするまで実行されるスライド ショーとして使用する場合は、次のことをお勧めします。

  • メソッドを呼び出すタイマー オブジェクトを使用して画像の数を増やし、画像を変更します。
  • GUI を一時停止するため、GUI で thread.sleep を使用しないでください。これは良いことではありません。

次/前のボタンを追加する場合は、増減できるグローバル インデックス (currentIndex など) が必要です。その後、コードを呼び出して画像を設定します。

于 2012-07-03T23:24:27.807 に答える
1

あなたの側でいくつかのセットアップが必要ですが、否定論者はほとんど正しいです. これは、本番アプリケーションにとってはあまり有効なソリューションではありません。そうは言っても、これがあなたが大量の人々に配布しているものであるとは思えないので、これを学術的な演習と呼びます。単純にアプリケーションにリソースを追加して「ImageResource」という名前を付け (任意の名前で構いません)、それに画像を追加する場合は、次のコードを使用できます (対応する UI 要素が存在すると仮定します)。

まず、リソースからビットマップを抽出する関数を作成します。

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();
}

そして出来上がり、リソースファイルからランダム化された画像。ハッピーコーディング!

編集: ランダムなリソース ファイルではなく、アプリケーション リソースを使用していると言ったことに気付きました。GetResourceImages で "ImageResource" を "Properties.Resources" に置き換えるだけで、すぐに使用できます。

于 2012-07-03T23:34:05.810 に答える
0

私は Ryan Ternier の答えが非常にシンプルでエレガントなのが好きです。彼に似た解決策を投稿するつもりでした。

行が機能しない/機能しない理由についてコメントしたいだけです。

画像 img = Properties.Resources.randomPictureName;

  1. これは、Properties Resources が実際の名前自体ではなく、「randomPictureName」というリソースを探しているためです。
  2. Properties.Resources オブジェクトが機能する方法は、コードのコンパイル後、実行時にソリューションのプロパティですべてのリソースを検索することです。リソースに存在しない可能性のある静的変数を渡そうとしているため、意図したとおりに機能しません。念のため、メソッドを try/catch ステートメントでラップする必要があります。

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

于 2012-07-04T00:07:36.610 に答える