コードでのWPFイメージソースの設定

2008年12月09日に質問されました。  ·  閲覧回数 553.3k回  ·  ソース

Torbjørn picture
2008年12月09日

WPFイメージのソースをコードで設定しようとしています。 画像はプロジェクトのリソースとして埋め込まれます。 例を見て、私は以下のコードを思いついた。 何らかの理由で機能しません-画像が表示されません。

デバッグすることで、ストリームに画像データが含まれていることがわかります。 では、何が問題なのですか?

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
PngBitmapDecoder iconDecoder = new PngBitmapDecoder(iconStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
ImageSource iconSource = iconDecoder.Frames[0];
_icon.Source = iconSource;

アイコンは次のように定義されています: <Image x:Name="_icon" Width="16" Height="16" />

回答

Jared Harley picture
2009年10月31日
425

あなたと同じ問題を抱えていて、いくつか読んだ後、私は解決策を発見しました-パックURI

私はコードで次のことをしました:

Image finalImage = new Image();
finalImage.Width = 80;
...
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png");
logo.EndInit();
...
finalImage.Source = logo;

または、別のBitmapImageコンストラクターを使用して以下を実行します。

finalImage.Source = new BitmapImage(
    new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));

URIは次の部分に分かれています。

  • 権限: application:///
  • パス:参照されるアセンブリにコンパイルされるリソースファイルの名前。 パスは次の形式に準拠している必要があります: AssemblyShortName[;Version][;PublicKey];component/Path

    • AssemblyShortName:参照されるアセンブリの短い名前。
    • ;バージョン[オプション]:リソースファイルを含む参照されるアセンブリのバージョン。 これは、同じ短い名前を持つ2つ以上の参照されるアセンブリがロードされるときに使用されます。
    • ; PublicKey [オプション]:参照されるアセンブリに署名するために使用された公開鍵。 これは、同じ短い名前を持つ2つ以上の参照されるアセンブリがロードされるときに使用されます。
    • ; component:参照されているアセンブリがローカルアセンブリから参照されることを指定します。
    • / Path:参照されているアセンブリのプロジェクトフォルダーのルートを基準にした、パスを含むリソースファイルの名前。

application:後の3つのスラッシュは、コンマに置き換える必要があります。

注:パックURIの権限コンポーネントは、パッケージを指す埋め込みURIであり、RFC 2396に準拠する必要があります。さらに、「/」文字を「、」文字、および「%」などの予約文字に置き換える必要があります。と「?」 エスケープする必要があります。 詳細については、OPCを参照してください。

そしてもちろん、イメージのビルドアクションをResource設定していることを確認してください。

Simon picture
2009年08月26日
176
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);

これにより、「WpfApplication1」というアセンブリの「ビルドアクション」が「リソース」に設定された「Images」というフォルダに「Untitled.png」という画像が読み込まれます。

Alex B picture
2010年01月07日
76

これは少し少ないコードであり、1行で実行できます。

string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
A Bothe picture
2010年12月13日
46

非常に簡単:

メニュー項目の画像を動的に設定するには、次の手順のみを実行します。

MyMenuItem.ImageSource = 
    new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));

...一方、「icon.ico」はどこにでも配置でき(現在は「Resources」ディレクトリにあります)、Resourceとしてリンクする必要があります...

Hasan picture
2011年11月17日
17

最も簡単な方法:

var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
Payson Welch picture
2011年02月14日
16

これを1行に減らすこともできます。 これは、メインウィンドウのアイコンを設定するために使用したコードです。 .icoファイルがコンテンツとしてマークされ、出力ディレクトリにコピーされていることを前提としています。

 this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
Andrew Myhre picture
2009年02月10日
15

やってみました:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
IlPADlI picture
2015年05月09日
13

これが私のやり方です:

internal static class ResourceAccessor
{
    public static Uri Get(string resourcePath)
    {
        var uri = string.Format(
            "pack://application:,,,/{0};component/{1}"
            , Assembly.GetExecutingAssembly().GetName().Name
            , resourcePath
        );

        return new Uri(uri);
    }
}

使用法:

new BitmapImage(ResourceAccessor.Get("Images/1.png"))
awe picture
2009年07月10日
8

イメージパスを動的に設定する例を次に示します(イメージはリソースとしてビルドするのではなく、ディスク上のどこかにあります)。

if (File.Exists(imagePath))
{
    // Create image element to set as icon on the menu element
    Image icon = new Image();
    BitmapImage bmImage = new BitmapImage();
    bmImage.BeginInit();
    bmImage.UriSource = new Uri(imagePath, UriKind.Absolute);
    bmImage.EndInit();
    icon.Source = bmImage;
    icon.MaxWidth = 25;
    item.Icon = icon;
}

アイコンについての考察...

最初に考えたのは、Iconプロパティには画像しか含めることができないと思うでしょう。 しかし、実際には何でも含めることができます! プログラムでImageプロパティを画像へのパスを含む文字列に直接設定しようとしたときに、これを偶然発見しました。 その結果、画像ではなく、パスの実際のテキストが表示されました。

これにより、アイコンの画像を作成する必要がなく、代わりにシンボルフォント付きのテキストを使用して、単純な「アイコン」を表示するという代替手段が得られます。 次の例では、「フロッピーディスク」記号を含むWingdingsフォントを使用しています。 この記号は実際には文字<であり、XAMLで特別な意味を持つため、代わりにエンコードされたバージョン&lt;を使用する必要があります。 これは夢のように機能します! 以下に、メニュー項目のアイコンとしてフロッピーディスクのシンボルを示します。

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>
</MenuItem>
Hollyroody picture
2017年05月15日
8

画像がResourceDictionaryに保存されている場合は、次の1行のコードで実行できます。

MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;