WPF 이미지 리소스


408

나는 주로 웹과 약간의 Windows Forms 배경에서 왔습니다. 새 프로젝트에서는 WPF를 사용합니다. WPF 응용 프로그램에는 설명을 위해 10-20 개의 작은 아이콘과 이미지가 필요합니다. 어셈블리에 이러한 리소스를 포함 된 리소스로 저장하려고합니다. 그것이 올바른 길입니까?

XAML에서 이미지 컨트롤이 포함 된 리소스에서 이미지를로드하도록 지정하려면 어떻게해야합니까?

답변:


473

여러 장소에서 이미지를 사용하는 경우 이미지 데이터를 메모리에 한 번만로드 한 다음 모든 Image요소 간에 공유하는 것이 좋습니다.

이렇게하려면 BitmapSource 어딘가에 리소스를 작성하십시오 .

<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />

그런 다음 코드에서 다음을 사용하십시오.

<Image Source="{StaticResource MyImageSource}" />

필자의 경우 Image.png파일을 Resource단순한 빌드 작업이 아닌 빌드 작업으로 설정해야한다는 것을 알았습니다 Content. 이렇게하면 이미지가 컴파일 된 어셈블리 내로 전달됩니다.


6
이 작업을 동적으로 수행 할 수 있습니까? 시작시로드 할 이미지 수가 다른 경우 이미지 당 BitmapSource를 만들어 위와 같은 방식으로 참조 할 수 있습니까?
Becky Franklin

2
@Becky-예. Xaml에서 참조하려면 컴파일 타임에 키를 알고 있다고 가정하고 DynamicResource대신 태그 확장 을 사용해야 할 수도 있습니다 StaticResource. WPF에서는 런타임에 리소스 사전을 만들 수 있습니다. 사실, 그것은 Xaml 문서를로드 할 때 발생하는 것입니다. 이는 동등한 C #을 볼 수 없다는 것입니다.
Drew Noakes

9
내가 겪은 것 : 이미지 리소스를 리소스 사전에 추가하는 경우 구성 요소의 XAML에서 해당 이미지 사전을 참조하는 것을 잊지 마십시오. <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source = "Dictionary1.xaml"/> </ResourceDictionary.MergedDictionaries> </ ResourceDictionary> </UserControl.Resources>
Dan Mitchell

4
그렇지 않으면 이미지가 어떤 이유로 (예 : 200x200 픽셀로 확장 된 16x16 아이콘과 같은) 그로테스크하게 확대되는 것을 종종 볼 수 있기 때문에 일반적으로에 추가 Width="{Binding Source.PixelWidth, RelativeSource={RelativeSource Self}}" 합니다 Image.
또는 매퍼

5
BitmapImage가 참조 된 어셈블리의 리소스 사전에 선언 된 경우 UriSource가 작동하려면 packURI 여야합니다. 그렇지 않으면 VS의 xaml 편집기에서 이미지를 볼 수 있지만 디버깅 할 때 이미지가 표시되지 않습니다. 패키지 URI : msdn.microsoft.com/en-au/library/aa970069(v=vs.100).aspx
실패 프로그래밍

174

이미지, 비디오 등을 사용하는 가장 좋은 방법은 다음과 같습니다.

  • 파일 "Build action""Content"로 변경하십시오 . 빌드 디렉토리로 복사를 확인하십시오 .
    • 솔루션 탐색기 창의 "오른쪽 클릭"메뉴에 있습니다.
  • 다음 형식의 이미지 소스 :
    • "/ «YourAssemblyName» ; component /«YourPath»/«YourImage.png» "

<Image Source="/WPFApplication;component/Images/Start.png" />

혜택:

  • 파일은 어셈블리에 포함되지 않습니다.
    • 리소스 관리자는 너무 많은 리소스 (빌드 타임에)로 메모리 오버플로 문제를 일으 킵니다.
  • 어셈블리간에 호출 할 수 있습니다.

36
어셈블리에 리소스를 포함하지만 "빌드 작업"을 "리소스"로 설정해야하는 경우에도 이와 동일한 방법이 작동합니다.
Ashley Davis

5
고마워요 "구성 요소"는 "있는 그대로"필요합니다. "이미지"는 프로젝트에서 png의 상대 경로입니다. 즉 루트에 배치 된 이미지는 "<Image Source ="/ WPFApplication; component / Start.png "/>"입니다.
Badiboy

3
C #에서이를 수행하는 방법의 예가 좋습니다. (이것은 유효한 URI가 아니므로 BitmapImage를 생성 할 때 사용할 수 없습니다.)
Vaccano

5
파일이 Embedded Resource로 설정된 경우 어떻게해야합니까? 작동하지 않는 것 같습니다. 그리고 프로젝트에 이미지를 두 번 포함하고 싶지 않습니다. (나는 이미 포함 된 리소스로 사용하고 있습니다.)
BrainSlugs83

2
"구성 요소"는 어디에서 어떻게 경로에 도달합니까? 그 사양의 일부입니까?
Triynko 2013

46

어떤 사람들은 코드 에서이 작업을 수행하고 답변을 얻지 못하고 있습니다.

많은 시간을 검색 한 후 매우 간단한 방법을 찾았고 예를 찾지 못했기 때문에 이미지와 작동하는 광산을 공유했습니다. (광산은 .gif였습니다)

요약:

ImageSource "목적지"가 좋아하는 BitmapFrame을 반환합니다.

사용하다:

doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");

방법:

static internal ImageSource doGetImageSourceFromResource(string psAssemblyName, string psResourceName)
{
    Uri oUri = new Uri("pack://application:,,,/" +psAssemblyName +";component/" +psResourceName, UriKind.RelativeOrAbsolute);
    return BitmapFrame.Create(oUri);
}

학습 :

내 경험에 따르면 팩 문자열이 문제가되지 않으므로 스트림을 확인하십시오. 특히 처음 읽을 때 포인터가 파일의 끝 부분에 포인터를 설정하고 다시 읽기 전에 0으로 다시 설정 해야하는 경우.

나는 이것이 당신이이 작품이 저를 위해 원하는 많은 시간을 절약하기를 바랍니다!


44

내 이미지 Freq.png가 폴더에 Icons있고 다음과 같이 정의 된 실행중인 어셈블리에 리소스를로드하는 코드에서 Resource:

this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/" 
    + Assembly.GetExecutingAssembly().GetName().Name 
    + ";component/" 
    + "Icons/Freq.png", UriKind.Absolute)); 

또한 기능을 만들었습니다.

/// <summary>
/// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
/// </summary>
/// <param name="pathInApplication">Path without starting slash</param>
/// <param name="assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling assembly</param>
/// <returns></returns>
public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
{
    if (assembly == null)
    {
        assembly = Assembly.GetCallingAssembly();
    }

    if (pathInApplication[0] == '/')
    {
        pathInApplication = pathInApplication.Substring(1);
    }
    return new BitmapImage(new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute)); 
}

사용법 (ResourceHelper 클래스에 함수를 넣었다고 가정) :

this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");

참고 : WPF의 MSDN Pack URI를 참조하십시오 .
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml


새 URI에서 잘못된 URI가 발생 함 : 잘못된 포트가 지정되었습니다.
Steve

문제가되는 URI가 있습니까?
Eric Ouellet

1
광산이 winform 호스팅 WPF 내에서 실행되고 있다는 점을 제외하고는 귀하와 동일한 URI입니다. 그리고 새 Uri를 호출했을 때 "pack"스키마가 아직 등록되지 않았습니다.
Steve

1
죄송합니다. 호스팅 WPF를 winform하는 것으로 보복되었을 것입니다. 죄송 해요. 나는 그것이 일반적인 사용법이 아니라고 생각하기 때문에 고치려고하지 않을 것입니다. 행운을 빕니다!
Eric Ouellet

제 경우 new Uri(@"pack://application:,,,/" + pathInApplication)에는를 사용 하여 트릭을 수행했습니다.
Adam Calvet Bohl

40

그렇습니다.

경로를 사용하여 리소스 파일에서 이미지를 사용할 수 있습니다.

<Image Source="..\Media\Image.png" />

이미지 파일의 빌드 조치를 "자원"으로 설정해야합니다.


1
고마워 ImageSource와 비슷한 작업을 수행하여 이미지를 리소스 사전에 한 번만로드하는 방법이 있습니까? 이 접근법은 이미지 데이터를 메모리에 여러 번로드 할까 걱정됩니다.
Drew Noakes

2
코드를 리팩터링해야 할 때 엉망이 될 것입니다. xaml 문서가 네임 스페이스를 변경하는 경우 모든 이미지 참조를 수동으로 변경해야합니다. Drew Noakes가 묘사 한 방법은 훨씬 더 매끄럽고 메인 테이블입니다.
카스퍼 홀덤

14

리소스 사용 방법에 대한 자세한 설명 : WPF 응용 프로그램 리소스, 콘텐츠 및 데이터 파일

그리고 그것들을 참조하는 방법은 "Pack URIs in WPF"를 읽으십시오.

요컨대, 참조 / 참조 어셈블리에서 리소스를 참조 할 수있는 수단도 있습니다.


링크가 제대로 작동하는 것 같습니다 ( "이 문서는 보관되어 있으며 유지 관리되지 않습니다"라고 표시되어 있음 ).
피터 Mortensen

5
  1. Visual Studio 2010 Professional SP1
  2. .NET Framework 4 클라이언트 프로파일.
  3. 프로젝트 속성에 리소스로 추가 된 PNG 이미지.
  4. Resources 폴더에 새 파일이 자동으로 생성됩니다.
  5. 조치 세트를 자원으로 빌드하십시오.

이것은 나를 위해 일했다 :

<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />

3

당신이 사용하는 경우 혼합을 , 추가 쉽게 그것을 확인하고 문제가에 대한 올바른 경로를 받고 있지하는 소스 속성 드래그하고 디자이너로 프로젝트 패널에서 이미지를 놓습니다.


3

예, 옳습니다. 경로를 사용하여 리소스 파일에서 이미지를 사용할 수 있습니다.

<StackPanel Orientation="Horizontal">
    <CheckBox  Content="{Binding Nname}" IsChecked="{Binding IsChecked}"/>
    <Image Source="E:\SWorking\SharePointSecurityApps\SharePointSecurityApps\SharePointSecurityApps.WPF\Images\sitepermission.png"/>
    <TextBlock Text="{Binding Path=Title}"></TextBlock>
</StackPanel>

-5

다음은 작동하고 설정할 이미지는 속성의 리소스입니다.

    var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
                                      IntPtr.Zero,
                                      Int32Rect.Empty,
                                      BitmapSizeOptions.FromEmptyOptions());
    MyButton.Background = new ImageBrush(bitmapSource);
img_username.Source = bitmapSource;

5
악의는 없지만 나쁜 습관처럼 들립니다.
ShloEmi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.