코드에서 WPF 이미지 소스 설정
코드에서 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" />
당신과 같은 문제가 있고 약간의 독서를 한 후에 솔루션 팩 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 : 참조 된 어셈블리의 짧은 이름입니다.
- ; Version [선택 사항] : 리소스 파일이 포함 된 참조 된 어셈블리의 버전입니다. 짧은 이름이 동일한 둘 이상의 참조 된 어셈블리가로드 될 때 사용됩니다.
- ; PublicKey [선택 사항] : 참조 된 어셈블리에 서명하는 데 사용 된 공개 키. 짧은 이름이 동일한 둘 이상의 참조 된 어셈블리가로드 될 때 사용됩니다.
- ; component : 참조되는 어셈블리가 로컬 어셈블리에서 참조되도록 지정합니다.
- / 경로 : 참조 된 어셈블리 프로젝트 폴더의 루트에 상대적인 경로를 포함한 리소스 파일의 이름.
세 개의 슬래시는 이후 application:
에 쉼표로 교체해야합니다.
참고 : 팩 URI의 권한 구성 요소는 패키지를 가리키는 임베디드 URI이며 RFC 2396을 준수해야합니다. 또한 "/"문자는 ","문자 및 "%"와 같은 예약 문자로 바꿔야합니다. "?" 탈출해야합니다. 자세한 내용은 OPC를 참조하십시오.
물론 이미지의 빌드 작업을로 설정했는지 확인하십시오 Resource
.
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);
"WpfApplication1"이라는 어셈블리에서 "Build Action"이 "Resource"로 설정된 "Images"폴더에 "Untitled.png"라는 이미지가로드됩니다.
이것은 약간 적은 코드이며 한 줄로 수행 할 수 있습니다.
string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
아주 쉽게:
메뉴 항목의 이미지를 동적으로 설정하려면 다음을 수행하십시오.
MyMenuItem.ImageSource =
new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));
"icon.ico"는 어디에나있을 수 있으며 (현재 'Resources'디렉토리에 위치) Resource로 링크되어야합니다.
이것을 한 줄로 줄일 수도 있습니다. 이것은 메인 윈도우의 아이콘을 설정하는 데 사용한 코드입니다. .ico 파일이 내용으로 표시되어 출력 디렉토리로 복사되고 있다고 가정합니다.
this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
가장 간단한 방법 :
var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
시도해 보셨습니까?
Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
이게 내 방법이야:
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"))
이미지 경로를 동적으로 설정하는 예는 다음과 같습니다 (이미지는 리소스로 빌드하지 않고 디스크 어딘가에 위치).
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
속성을 이미지 경로가있는 문자열 로 설정하려고 시도했을 때 우연히이 사실을 발견했습니다 . 결과는 이미지가 아니라 경로의 실제 텍스트입니다!
이로 인해 아이콘 이미지를 만들 필요는 없지만 간단한 "아이콘"을 표시하기 위해 기호 글꼴이있는 텍스트를 사용할 수 있습니다. 다음 예제에서는 "floppydisk"기호가 포함 된 Wingdings 글꼴 을 사용합니다 . 이 기호는 실제로 문자 <
이므로 XAML에서 특별한 의미를 가지므로 <
대신 인코딩 된 버전을 사용해야합니다 . 이것은 꿈처럼 작동합니다! 다음은 메뉴 항목에서 플로피 디스크 기호를 아이콘으로 나타냅니다.
<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
<MenuItem.Icon>
<Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings"><</Label>
</MenuItem.Icon>
</MenuItem>
이미지가 ResourceDictionary에 저장된 경우 한 줄의 코드만으로 이미지를 수행 할 수 있습니다.
MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;
더 간단한 방법도 있습니다. 이미지가 XAML에서 리소스로로드되고 해당 코드가 해당 XAML 콘텐츠의 코드 숨김 인 경우 :
Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute);
NotifyIcon.Icon = BitmapFrame.Create(iconUri);
VisualBrush에 프레임을 넣습니다.
VisualBrush brush = new VisualBrush { TileMode = TileMode.None };
brush.Visual = frame;
brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;
GeometryDrawing에 VisualBrush를 넣습니다
GeometryDrawing drawing = new GeometryDrawing();
drawing.Brush = brush;
// Brush this in 1, 1 ratio
RectangleGeometry rect = new RectangleGeometry { Rect = new Rect(0, 0, 1, 1) };
drawing.Geometry = rect;
이제 GeometryDrawing을 DrawingImage에 넣습니다.
new DrawingImage(drawing);
이것을 이미지의 소스에 올려 놓으십시오!
그래도 훨씬 쉽게 할 수 있습니다.
<Image>
<Image.Source>
<BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
</Image.Source>
</Image>
그리고 코드에서 :
BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };
더 간단한 방법도 있습니다. 이미지가 XAML에서 리소스로로드되고 해당 코드가 해당 XAML의 코드 숨김 인 경우 :
XAML 파일에 대한 리소스 사전은 다음과 같습니다. "PosterBrush"키가있는 ImageBrush 만 있으면됩니다. 나머지 코드는 컨텍스트를 표시하기위한 것입니다.
<UserControl.Resources>
<ResourceDictionary>
<ImageBrush x:Key="PosterBrush" ImageSource="..\Resources\Images\EmptyPoster.jpg" Stretch="UniformToFill"/>
</ResourceDictionary>
</UserControl.Resources>
이제 코드 뒤에, 당신은 이것을 할 수 있습니다
ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"];
리소스 아이콘 및 이미지에 포함 된 이미지를로드하는 방법 (수정 된 버전의 Arcturus) :
이미지가있는 버튼을 추가한다고 가정합니다. 어떻게해야합니까?
- 프로젝트 폴더 아이콘에 추가하고 이미지를 여기에 클릭하십시오. ClickMe.png
- 'ClickMe.png'의 속성에서 'BuildAction'을 'Resource'로 설정하십시오.
- 컴파일 된 어셈블리 이름이 'Company.ProductAssembly.dll'이라고 가정하십시오.
이제 XAML에 이미지를로드 할 차례입니다
<Button Width="200" Height="70"> <Button.Content> <StackPanel> <Image Width="20" Height="20"> <Image.Source> <BitmapImage UriSource="/Company.ProductAssembly;component/Icons/ClickMe.png"></BitmapImage> </Image.Source> </Image> <TextBlock HorizontalAlignment="Center">Click me!</TextBlock> </StackPanel> </Button.Content> </Button>
끝난.
WPF를 처음 사용하지만 .NET에는 없습니다.
.NET 3.5 (Visual Studio 2010)의 "WPF Custom Control Library Project"에 PNG 파일을 추가하고 이미지 상속 컨트롤의 배경으로 설정하는 데 5 시간을 보냈습니다.
URI와 관련된 것은 없습니다. IntelliSense를 통해 리소스 파일에서 URI를 가져 오는 방법이없는 이유를 상상할 수 없습니다.
Properties.Resources.ResourceManager.GetURI("my_image");
나는 많은 URI를 시도하고 ResourceManager와 Assembly의 GetManifest 메소드를 가지고 놀았지만 모두 예외 또는 NULL 값이있었습니다.
여기에 나를 위해 일한 코드가 있습니다.
// Convert the image in resources to a Stream
Stream ms = new MemoryStream()
Properties.Resources.MyImage.Save(ms, ImageFormat.Png);
// Create a BitmapImage with the stream.
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();
// Set as source
Source = bitmap;
이미 스트림이 있고 형식을 알고 있다면 다음과 같이 사용할 수 있습니다.
static ImageSource PngStreamToImageSource (Stream pngStream) {
var decoder = new PngBitmapDecoder(pngStream,
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
return decoder.Frames[0];
}
당신은 조금 놓쳤다.
어셈블리에서 임베디드 리소스를 얻으려면 여기에서 언급 한 것처럼 파일 이름으로 어셈블리 이름을 언급해야합니다.
Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream(asm.GetName().Name + "." + "Desert.jpg");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
image1.Source = bitmap;
참고 URL : https://stackoverflow.com/questions/350027/setting-wpf-image-source-in-code
'Programing' 카테고리의 다른 글
그룹별로 변수를 합산하는 방법 (0) | 2020.03.11 |
---|---|
DIV의 내용을 인쇄 (0) | 2020.03.11 |
.NET DateTime에서 밀리 초를 자르는 방법 (0) | 2020.03.11 |
π의 가치를 얻는 가장 빠른 방법은 무엇입니까? (0) | 2020.03.11 |
Eclipse에서 빵 부스러기를 비활성화하는 방법 (0) | 2020.03.11 |