1

I am trying to load a DirectDraw Surface (DDS) file and display it in a WPF application. This is how I get the stream from a zip archive:

using (ZipArchive clientArchive = ZipFile.OpenRead(levelsPath + mapName + @"\client.zip"))
{
    var entry = clientArchive.GetEntry("hud/minimap/ingamemap.dds");
    var stream = entry.Open();
}

Now, how do I display the DDS image (just the first, highest quality mipmap) in my WPF application?

2 Answers2

2

I recently used DDSImage class from kprojects. It can load DXT1 and DXT5 compressend DDS files.

Simply create a new instance with a byte array and access all mipmaps through the property images of type Bitmap[]:

DDSImage img = new DDSImage(File.ReadAllBytes(@"e:\myfile.dds"));

for (int i = 0; i < img.images.Length; i++)
{
    img.images[i].Save(@"e:\mipmap-" + i + ".png", ImageFormat.Png);
} 

Im you got your mipmap as Bitmap you could display it with an Image-Control. To create an BitmapSource, based on the Bitmap in memory this answer pointed me the right way.

Community
  • 1
  • 1
devmb
  • 805
  • 6
  • 18
0
using (ZipArchive clientArchive = ZipFile.OpenRead(levelsPath + mapName + @"\client.zip"))
{
    var entry = clientArchive.GetEntry("hud/minimap/ingamemap.dds");
    var stream = entry.Open();
    ImageObject.Source = DDSConverter.Convert(stream,null,null,null);
}

Taken from here.

public class DDSConverter : IValueConverter
{
    private static readonly DDSConverter defaultInstace = new DDSConverter();

    public static DDSConverter Default
    {
        get
        {
            return DDSConverter.defaultInstace;
        }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }
        else if (value is Stream)
        {
            return DDSConverter.Convert((Stream)value);
        }
        else if (value is string)
        {
            return DDSConverter.Convert((string)value);
        }
        else if (value is byte[])
        {
            return DDSConverter.Convert((byte[])value);
        }
        else
        {
            throw new NotSupportedException(string.Format("{0} cannot convert from {1}.", this.GetType().FullName, value.GetType().FullName));
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException(string.Format("{0} does not support converting back.", this.GetType().FullName));
    }

    public static ImageSource Convert(string filePath)
    {
        using (var fileStream = File.OpenRead(filePath))
        {
            return DDSConverter.Convert(fileStream);
        }
    }

    public static ImageSource Convert(byte[] imageData)
    {
        using (var memoryStream = new MemoryStream(imageData))
        {
            return DDSConverter.Convert(memoryStream);
        }
    }

    public static ImageSource Convert(Stream stream)
    {
        ...
    }
}

Following is a simple usage example:

<Image x:Name="ImageObject" Source="{Binding Source=Test.dds, Converter={x:Static local:DDSConverter.Default}}" />
Bura Chuhadar
  • 3,653
  • 1
  • 14
  • 17
  • This solution requires me to install XNA 3.1 (4.0 won't work since some of the methods/classes are not there anymore) which in turn requires me to install Visual C# Studio Express Edition 2008 (which I don't want since I have VS2013). This does not solve my problem. – aPerfectMisterMan May 13 '14 at 07:13