对于Windows XP SP3上的GIF图像,元数据为空(在Windows 7上可以正常使用)

| 我有以下代码,这些代码使用WPF图像处理API打印图像的元数据:
void Main()
{
    Uri imageUri = new Uri(@\"E:\\tmp\\bomb.gif\");
    var decoder = BitmapDecoder.Create(imageUri, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    var f = decoder.Frames[0];
    var m = f.Metadata as BitmapMetadata;
    DumpMetadata(m);
}

void DumpMetadata(BitmapMetadata metadata)
{
    DumpMetadata(metadata, 0);
}

void DumpMetadata(BitmapMetadata metadata, int indentLevel)
{
    if (metadata == null)
    {
        Console.WriteLine (\"(No metadata)\");
        return;
    }
    string indent = new string(\'\\t\', indentLevel);
    foreach (var propertyName in metadata)
    {
        object value = metadata.GetQuery(propertyName);
        BitmapMetadata complexProperty = value as BitmapMetadata;
        if (complexProperty != null)
        {
            Console.WriteLine(\"{0}{1} =\", indent, propertyName);
            DumpMetadata(complexProperty, indentLevel + 1);
        }
        else
        {
            Type type = null;
            if (value != null)
                type = value.GetType();
            Console.WriteLine(\"{0}{1} = {2} ({3})\", indent, propertyName, value, type);
        }
    }
}
在Windows 7上,它给出正确的结果:
/imgdesc =
  /Left = 0 (System.UInt16)
  /Top = 0 (System.UInt16)
  /Width = 78 (System.UInt16)
  /Height = 121 (System.UInt16)
  /LocalColorTableFlag = False (System.Boolean)
  /InterlaceFlag = False (System.Boolean)
  /SortFlag = False (System.Boolean)
  /LocalColorTableSize = 7 (System.Byte)
/grctlext =
  /Disposal = 2 (System.Byte)
  /UserInputFlag = False (System.Boolean)
  /TransparencyFlag = True (System.Boolean)
  /Delay = 10 (System.UInt16)
  /TransparentColorIndex = 0 (System.Byte)
但是在Windows XP(SP3)上,GIF图像(是否经过动画处理)的
Metadata
属性始终为null。 我认为该问题可能与Windows Imaging Component有关,但是WIC应该与SP3一起安装(并且是.NET 3.0的一部分;我在该PC上具有3.5 SP1和4.0),因此它也可以在XP上运行。 不知道这里发生了什么...仅仅是缺少编解码器吗?有没有办法使此代码在XP上有效? 编辑:我需要的信息是3域(帧的持续时间);如果我收不到
BitmapMetadata
,还有其他方法可以提取此信息吗?理想情况下,我宁愿只使用WPF图像处理API(即不使用GDI / System.Drawing)。 更新:我在MSDN论坛上发布了相同的问题,根据我收到的答案,只有Windows 7和带有Platform Update的Vista才支持GIF元数据(请参见此处和此处)。因此,我想使用WPF图像API使其无法在XP上运行是不可能的。我可能最终会使用System.Drawing,但是我愿意接受更好的建议...
已邀请:
没错,问题出在XP中的WIC。该线程还提到了该问题。 但是,使用来自GDI +的旧
System.Drawing
,您可以执行以下操作:
private static int ReadGifDelayInMiliseconds(string gifFile, int frameIndex = 0)
{
    System.Drawing.Image img = System.Drawing.Image.FromFile(gifFile);
    int numFrames = img.GetFrameCount(FrameDimension.Time);
    byte[] bytes = img.GetPropertyItem(0x5100).Value;
    if (frameIndex < numFrames)
    {
        var raw = BitConverter.ToInt32(bytes, frameIndex *  4);
        return raw * 10;
    }
    else
    {
        return -1;
    }       
}
注意,由于“ 7”数组具有所有延迟,因此您可以修改函数以一次读取所有帧的延迟。
我最终通过编写一个自定义的GIF解码器解决了这个问题,因为我只需要元数据,所以这并不困难。

要回复问题请先登录注册