Метаданные для образов GIF в Windows XP SP3 не имеют значения (отлично работает в Windows 7) - PullRequest
2 голосов
/ 19 апреля 2011

У меня есть следующий фрагмент кода, который печатает метаданные изображения с помощью API формирования изображений WPF:

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) свойство Metadata всегда равно нулю для изображений GIF (анимированных или нет).

Я думаю, что проблема может быть связана с Windows Imaging Component, но WIC должен быть установлен с SP3 (а также как часть .NET 3.0; у меня 3.5 SP1 и 4.0 на этом ПК), поэтому он должен работать на ХР тоже.

Не уверен, что здесь происходит ... Это просто отсутствующий кодек? Есть ли способ заставить этот код работать на XP?

РЕДАКТИРОВАТЬ: мне нужна информация о Delay поле (длительность кадра); если я не могу получить BitmapMetadata, есть ли другой способ извлечь эту информацию? В идеале я бы предпочел использовать только API для создания образов WPF (т.е. не GDI / System.Drawing).


ОБНОВЛЕНИЕ: я разместил тот же вопрос на форумах MSDN , и, согласно полученному ответу, метаданные GIF поддерживаются только в Windows 7 и в Vista с обновлением платформы ( см. Здесь и там ). Так что я думаю, что просто невозможно заставить его работать на XP с использованием API-образа WPF. Я, вероятно, в конечном итоге использовать System.Drawing, но я открыт для лучших предложений ...

Ответы [ 2 ]

1 голос
/ 29 мая 2014

Вы правы, проблема с WIC в XP. В этой теме также упоминается эта проблема.

Однако, используя старый System.Drawing из GDI +, вы можете сделать что-то вроде этого:

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

Обратите внимание, что вы можете изменитьфункция для считывания задержки каждого кадра сразу, поскольку массив bytes имеет все задержки.

0 голосов
/ 29 ноября 2011

Я в конце концов решил эту проблему, написав собственный GIF-декодер, что не слишком сложно, так как мне нужны только метаданные ...

...