Question

I am writing a program that has to access images from a legacy data file format. (To be specific: The program is loading it's UI images directly from the data files of an old game) Since the images are all stored as Targa (TGA) files, I have to preprocess them into PNG files. I do that in a local application data folder.

My problem is writing/authoring XAML files using these images. Since I don't want to redistribute the images (Copyright issues), I can't just include them as resources in my application. This excludes the normal way of including images in WPF controls.

What I've successfully tried is putting the preprocessed images in the same directory as the application's assembly and reference them using "pack://siteoforigin:,,,/cache/image.png". This also works from within the XAML Designer in Visual Studio as well as Expression Blend 3.

The issue with this approach is, that the application's directory is not neccessarily writable as the current user (Especially if the application resides in C:\Program Files), so storing the images there during the pre-process phase is out of the question for me.

An alternative approach I successfully used is creating a custom WebRequest protocol like cache:// and use that for the image URLs. This works in the actual application, but not in Visual Studio's designer or Expression Blend.

Is anyone aware of another good way to reference images in the filesystem using WPF? Or some way to customize the resource loading, that is compatible with the usual WPF Authoring solutions?

Was it helpful?

Solution

To answer my own question:

I had to implement two MarkupExtensions: One that creates an ImageSource and one that creates an ImageBrush. Those classes created the objects using relative URLs (relative to the local cache in %appdata%).

Then I was able to use:

<Grid Background="{local:LocalImageBrush Filename=some/relative/filename.png}" />

The code for the markup extension is:

class LocalImageBrush : MarkupExtension
{
  public string Filename { get; set; }

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    var result = new Uri("file:///" + ProfileDirectory.LocalDataPath + "/" + Filename);
    return new ImageBrush(new BitmapImage(result));
  }
}

This also works in the Visual Studio IDE.

OTHER TIPS

You can write your images to a subfolder of %APPDATA% which is writable. You get the path with Environment.SpecialFolder.ApplicationData

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top