从流中加载DDS文件并在WPF应用程序中显示

本文关键字:WPF 应用程序 显示 文件 加载 DDS | 更新日期: 2023-09-27 18:02:53

我正在尝试加载DirectDraw Surface (DDS)文件并在WPF应用程序中显示它。下面是我从zip存档文件中获取流的方法:

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

现在,我如何在WPF应用程序中显示DDS图像(只是第一个,最高质量的mipmap) ?

从流中加载DDS文件并在WPF应用程序中显示

我最近使用了来自kprojects的DDSImage类。它可以加载DXT1和DXT5压缩DDS文件。

用字节数组创建一个新的实例,并通过Bitmap[]类型的images属性访问所有的mipmap:

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);
} 

如果你的mipmap是Bitmap,你可以用Image-Control来显示它。要创建一个BitmapSource,基于内存中的位图,这个答案为我指出了正确的方法。

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);
}

从这里取。

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)
    {
        ...
    }
}

下面是一个简单的用法示例:

<Image x:Name="ImageObject" Source="{Binding Source=Test.dds, Converter={x:Static local:DDSConverter.Default}}" />