none
C# RecouceManagerから取得した画像をファイルパスで区別したい RRS feed

  • 質問

  • ResouceManagerを使用して画像の名前をリストに格納するソースコードを作りましたが、10種類以上の画像を2種類に区別したい。

    2種類を区別を以下のファイルパスでしたいです
    bin/Resources/img/ppap
    bin/Resources/img/glassan

    iconの名前に区別する語句を入れる方法
    例えば
    ppap_apple.png
    ppap_pineapple.png
    glassan_pen.png

    この方法では実現できましたが、ファイルパスを使って同じ結果を得たいです。

    以下のソースコードではppapとglassan中の画像名を区別することができません。

    どうかご教授お願い致します。

    main(){
    //REsourceManagerを使用して画像を取得する
            foreach (KeyValuePair<string,Bitmap> resourceIconsName in Properties.Resources.ResourceManager.getEntries<Bitmap>())
        {
            userIconName.Add(resourceIconsName.Key);//valueが画像,keyがファイル名
        }
    }
    public static IEnumerable<KeyValuePair<string, T>> getEntries<T>(this ResourceManager rman)
    {
    return rman.GetResourceSet(System.Threading.Thread.CurrentThread.CurrentCulture, true, true).OfType<DictionaryEntry>().Where(e => e.Value is T).Select(e => new KeyValuePair<string, T>((string)e.Key, (T)e.Value));
    }
    ```

    2020年1月10日 20:02

回答

  • 方法1:
    Properties\Resources.resxに入れた各イメージの名前にファイルパス文字'\'(半角円記号)あるいは'/'(スラッシュ)を加える。
     bin\Resources\img\ppap\apple.png
     bin/Resources/img\ppap\apple.png

    警告はでるが、ResourceManagerのKeyとしては有効なので、Keyでのみ取り出すのであれば使用できます。
    ディレクトリ構造は

    string dir = System.IO.Path.GetDirectoryName(resourceIconsName.Key);

    で取り出せる。
    ただしWindows以外の環境で実行する場合はセパレータ文字が違う可能性があるの注意は必要。

    方法2:
    Propertiesフォルダにリソースファイルを追加して、Properties\ppap.resx と Properties\glassan.resx という名前にする。
    それぞれのリソースに分類したイメージを追加していく。
    取り出しは以下のように。

    Properties.ppap.ResourceManager.getEntries<Bitmap>();
    Properties.glassan.ResourceManager.getEntries<Bitmap>();

    方法3:
    Resource.resxを使わずに、各画像のビルドアクションを「埋め込みリソース」にする。
    (ただしファイル名やディレクトリに拡張子指定以外のドットを含んではいけない)
    名前の列挙と取り出しは以下のように

    foreach (string name in typeof(Program).Assembly.GetManifestResourceNames())
    {
        if (name.EndsWith(".png", StringComparison.Ordinal))
        {
            var parts = name.Split('.');
            string fileName = string.Join(".", parts.Skip(parts.Length - 2));
            string dir = string.Join(System.IO.Path.DirectorySeparatorChar.ToString(), parts.Take(parts.Length - 2));
    
            System.Diagnostics.Debug.WriteLine(dir + "\t" + fileName);
    
            using (System.IO.Stream stream = typeof(Program).Assembly.GetManifestResourceStream(name))
            {
                var bitmap = System.Drawing.Bitmap.FromStream(stream);
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2020年1月11日 1:58
    • 回答としてマーク yurusite4 2020年1月11日 12:26
    2020年1月11日 1:53
  • であれば、そもそも既に同名のものが存在しているリソースを新たに追加した時点で、名前が自動的に変更されて連番が付加されますよね。

    また、リソースにファイルを追加したときにそのファイルが存在していたディレクトリ情報は、リソースには残っていません。

    なので、結局は追加時にリソース名を編集してどうにかする必要があります。

    • 回答としてマーク yurusite4 2020年1月11日 12:38
    2020年1月11日 2:19

すべての返信

  • まず確認したいのですが、そのリソースというのはどういうやり方でリソースに登録されていますか?

    例えば、プロジェクトのプロパティの「リソース」から「リソースの追加」で追加していったとか。

    2020年1月11日 0:43
  • おっしゃる通りプロジェクトのプロパティの「リソース」から「リソースの追加」で追加しています。
    2020年1月11日 1:33
  • 方法1:
    Properties\Resources.resxに入れた各イメージの名前にファイルパス文字'\'(半角円記号)あるいは'/'(スラッシュ)を加える。
     bin\Resources\img\ppap\apple.png
     bin/Resources/img\ppap\apple.png

    警告はでるが、ResourceManagerのKeyとしては有効なので、Keyでのみ取り出すのであれば使用できます。
    ディレクトリ構造は

    string dir = System.IO.Path.GetDirectoryName(resourceIconsName.Key);

    で取り出せる。
    ただしWindows以外の環境で実行する場合はセパレータ文字が違う可能性があるの注意は必要。

    方法2:
    Propertiesフォルダにリソースファイルを追加して、Properties\ppap.resx と Properties\glassan.resx という名前にする。
    それぞれのリソースに分類したイメージを追加していく。
    取り出しは以下のように。

    Properties.ppap.ResourceManager.getEntries<Bitmap>();
    Properties.glassan.ResourceManager.getEntries<Bitmap>();

    方法3:
    Resource.resxを使わずに、各画像のビルドアクションを「埋め込みリソース」にする。
    (ただしファイル名やディレクトリに拡張子指定以外のドットを含んではいけない)
    名前の列挙と取り出しは以下のように

    foreach (string name in typeof(Program).Assembly.GetManifestResourceNames())
    {
        if (name.EndsWith(".png", StringComparison.Ordinal))
        {
            var parts = name.Split('.');
            string fileName = string.Join(".", parts.Skip(parts.Length - 2));
            string dir = string.Join(System.IO.Path.DirectorySeparatorChar.ToString(), parts.Take(parts.Length - 2));
    
            System.Diagnostics.Debug.WriteLine(dir + "\t" + fileName);
    
            using (System.IO.Stream stream = typeof(Program).Assembly.GetManifestResourceStream(name))
            {
                var bitmap = System.Drawing.Bitmap.FromStream(stream);
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2020年1月11日 1:58
    • 回答としてマーク yurusite4 2020年1月11日 12:26
    2020年1月11日 1:53
  • であれば、そもそも既に同名のものが存在しているリソースを新たに追加した時点で、名前が自動的に変更されて連番が付加されますよね。

    また、リソースにファイルを追加したときにそのファイルが存在していたディレクトリ情報は、リソースには残っていません。

    なので、結局は追加時にリソース名を編集してどうにかする必要があります。

    • 回答としてマーク yurusite4 2020年1月11日 12:38
    2020年1月11日 2:19