2011-04-19 3 views
2

i를 WPF 이미징 API 사용하여 이미지의 메타 데이터 출력 다음 코드 조각이 : Windows에서메타 데이터 (Windows 7에서 잘 작동) 윈도우 XP SP3에서 GIF 이미지에 대한 null의

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

을 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) 

그러나 윈도우 XP (SP3)에

에서, Metadata 속성은 항상 GIF 이미지 (애니메이션 여부)에 대해 null입니다.

이 문제는 Windows Imaging Component와 관련이있을 수 있지만 WIC는 SP3 (또한 .NET 3.0의 일부로, 3.5 SP1 및 4.0이 해당 PC에 있음)과 함께 설치되어야하므로 작동해야합니다. XP에서도.

여기에 무슨 일이 일어나는지 확실하지 않습니다 ... 그냥 누락 된 코덱입니까? XP에서이 코드를 작동시키는 방법이 있습니까?

편집 : 필요한 정보는 Delay 필드 (프레임 지속 시간)입니다. BitmapMetadata을 얻을 수없는 경우이 정보를 추출 할 수있는 다른 방법이 있습니까? 이상적으로는 WPF 이미징 API (즉, GDI/System.Drawing 아님) 만 사용하는 것이 좋습니다.


UPDATE : 나는 같은 질문 on the MSDN forums를 게시하고받은 답변에 따라, GIF 메타 데이터는 Windows 7에서 지원하고 있으며, 플랫폼 업데이트 (see herethere)와 Vista에서. 그래서 WPF 이미징 API를 사용하여 XP에서 작동하도록 만드는 것은 불가능합니다. 아마도 System.Drawing을 사용하게 될 것이지만 더 나은 제안을 할 수는 있습니다. ...

답변

0

메타 데이터 만 필요하기 때문에 최종적으로 사용자 정의 GIF 디코더를 작성하여 해결했습니다.

1

맞습니다. 문제는 XP의 WIC에 있습니다. This thread에도이 문제가 언급되어 있습니다.

그러나 이전 System.Drawing GDI에서 사용 + 당신은 같은 것을 할 수있는 다음 bytes 배열이 모든 지연이 있기 때문에

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

주 당신이 한 번에 모든 프레임의 지연을 읽을 수있는 기능을 수정할 수 있습니다 .

+0

감사합니다. System.Drawing을 사용하지 않고 작업을 수행 할 수있는 사용자 지정 디코더를 이미 가지고 있습니다. –

+0

제발 ... 제발 ... 그냥 사용 가능한 방법을 사용했기 때문에 방금 지적했습니다. .넷 프레임 워크. 그러나 이미 배포 된 DLL의 일부인 디코더를 사용하고 있다면 지금 변경할 이유가 없습니다. –