MonoMac System.Drawing.Image.GetPropertyItem(0x5100)

dsf*_*sho 7 c# mono system.drawing gdi image

最近,我试图回答关于加载动画的帧(位图和持续时间)的另一个问题GIFs.代码可以在pastenbin找到.

在将此代码移入我的开发库之前对此代码进行其他测试时,我注意到这行代码存在问题:

//Get the times stored in the gif
//PropertyTagFrameDelay ((PROPID) 0x5100) comes from gdiplusimaging.h
//More info on http://msdn.microsoft.com/en-us/library/windows/desktop/ms534416(v=vs.85).aspx
var times = img.GetPropertyItem(0x5100).Value;
Run Code Online (Sandbox Code Playgroud)

当使用此(例如GIF)在Windows .Net上运行此数组时,该数组的大小与动画中的帧数相同,GIF并填充帧的持续时间.在这种情况下,一个字节[20]转换为(BitConverter.ToInt32())5个持续时间:

[75,0,0,0,125,0,0,0,125,0,0,0,125,0,0,0,250,0,0,0]
Run Code Online (Sandbox Code Playgroud)

但是,在MonoMac上,同一个示例GIF的这行代码返回一个byte[4]只转换为一个持续时间(第一个)的代码:

[75,0,0,0]
Run Code Online (Sandbox Code Playgroud)

我测试了10个不同GIF's的结果,结果总是一样的.在Windows上,所有持续时间都在byte []中,而MonoMac仅列出第一个持续时间:

[x,0,0,0]
[75,0,0,0]
[50,0,0,0]
[125,0,0,0]
Run Code Online (Sandbox Code Playgroud)

查看Mono System.Drawing.Image 源代码,似乎在此方法中设置了长度,这是一个GDI包装器:

status = GDIPlus.GdipGetPropertyItemSize (nativeObject, propid,out propSize);
Run Code Online (Sandbox Code Playgroud)

但是,我没有看到任何问题,不像我的实现那样使用源代码.我错过了什么或这是一个错误吗?

Jes*_*ter 1

如果您查看 libgdiplus,您会发现属性总是从活动位图中读取:

if (gdip_bitmapdata_property_find_id(image->active_bitmap, propID, &index) != Ok) {
Run Code Online (Sandbox Code Playgroud)

您可以通过调用Image.SelectActiveFrame设置活动位图,然后 mono 将一一返回正确的持续时间。由于这是与 Windows 不兼容的问题,我将其称为单声道错误。作为一个简单的解决方法,您当然可以只检查数组长度并处理这两种情况。这比检查单声道更好,因为如果单声道得到修复,这将继续工作。