2013-07-21 1 views
7

최근에 애니메이션 GIFs의 프레임 (비트 맵 및 기간)을로드하는 데 대해 SO question에 응답하려고했습니다. 코드는 pastenbin에 있습니다.MonoMac System.Drawing.Image.GetPropertyItem (0x5100)

내 dev 라이브러리로 이동하기 전에이 코드에 대한 추가 시험을하는 동안, 나는 코드 줄에 문제가있는 것으로 나타났습니다 :

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

이를 사용하여 Windows 닷넷에서이 작업을 실행 (example GIF) 배열의 애니메이션 크기는 애니메이션의 프레임 수와 동일하며 GIF이며 프레임의 지속 시간으로 채워집니다. (BitConverter.ToInt32()) 5 기간에 변환이 경우의 바이트 [20]에 MonoMac

[75,0,0,0,125,0,0,0,125,0,0,0,125,0,0,0,250,0,0,0] 

그러나, 예컨대 동일한 코드 행은 GIF로 변환 byte[4] 반환 한 시간 (첫 번째) :

[75,0,0,0] 

나는 10 가지 GIF's이 테스트 결과는 항상 동일합니다. MonoMac는 첫 번째 기간 나열하면서 Windows의 모든 기간이, 바이트 []에 있습니다

[x,0,0,0] 
[75,0,0,0] 
[50,0,0,0] 
[125,0,0,0] 

는 모노 System.Drawing.Image source code를 찾고, 길이는 GDI 래퍼입니다이 방법으로 설정하는 것 :

status = GDIPlus.GdipGetPropertyItemSize (nativeObject, propid,out propSize); 

그러나 실제로 구현과 관련하여 소스와 관련하여 문제가 발생하지 않습니다. 나는 뭔가를 놓치고 있거나 이것이 버그인가?

+0

나는 당신이 Mono GDI Plus 구현에서 대답을 찾을 것이라고 생각합니다. 나는 그것을 살펴 봤지만 gif 코덱에 대한 전문 지식이 없어서 무슨 일이 일어나는지 해독 할 수는 없습니다. 다음은 제가 발견 한 것입니다. [Image.FromFile] (https://github.com/mono/mono/blob/master/mcs/class/System.Drawing/System.Drawing/Image.cs)은 [libgdiplus] (https : // github. com/mono/libgdiplus/tree/master/src). libgdiplus 안에는 이미지를로드하는 함수가 있습니다. [gifcodec.c] 파일 (https://github.com/mono/libgdiplus/blob/master/src/gifcodec.c)의'gdip_load_gif_image' 함수는 gif 이미지를로드합니다. –

+0

'gdip_load_gif_image' 내부에서 어떤 일이 일어나는지 살펴볼 필요가 있습니다. 앞서 언급했듯이 이미지가로드/디코드되고 버그가 어디 있는지 추측 할 수 있습니다. 나는 무슨 일이 일어나고 있는지 파악할 수있는 GIF 전문 지식이 없습니다. 행운을 빕니다. –

답변

1

당신이 속성은 항상 활성 비트 맵에서 읽은 것을 볼 수 look into libgdiplus 경우

if (gdip_bitmapdata_property_find_id(image->active_bitmap, propID, &index) != Ok) { 

당신은 Image.SelectActiveFrame를 호출하여 활성 비트 맵을 설정하고 다음 모노 하나, 하나를 올바른 기간을 반환합니다. 이것은 Windows와 호환되지 않기 때문에 모노 버그라고 부릅니다. 간단한 해결 방법으로 배열 길이를 확인하고 두 경우 모두 처리 할 수 ​​있습니다. 모노가 고정되면이 작업이 계속 될 것이기 때문에 이것은 모노에 대한 검사보다 낫습니다.

+0

크로스 플랫폼 호환성 제안에 큰 도움을 주신 데 대해 감사드립니다. – dsfgsho

2

모노 소스에도 문제가 없습니다. 시도한 견본 이미지 중 하나를 올렸다면 도움이 될 것입니다. GIF 이미지 형식에 관한 한 가지 단점은 프레임 시간이 포함 된 그래픽 제어 확장 블록이 (선택 사항)이며 이미지 설명자보다 먼저 생략 될 수 있다는 것입니다. 모든 프레임에 적용되는 GCE 파일이 하나 뿐인 GIF 파일을 가지고 있기 때문에 모든 프레임에 동일한 프레임 시간을 적용해야합니다.

4 개의 값을 가져 오지 않았 음을 유의하십시오. 프레임 시간은 32 비트 값으로 인코딩되며 바이트 []에서 리틀 엔디안 인코딩을 보게됩니다. 샘플 코드에서 올바르게 수행 한 것처럼 BitConverter.ToInt32()를 사용해야합니다. 프레임 번호와 동일한 크기 일 필요는 없습니다 최대 2 프레임,

//convert 4 bit value to integer 
var duration = BitConverter.ToInt32(times, 4*i % times.Length); 

은 GIF 프레임에 대한 또 다른 불쾌한 구현 세부 거기에 있습니다 말고 :

나는 그러므로 당신은 아마 대신을 사용한다고 생각합니다 1. 그리고 각 프레임에는 이전 프레임과 다음 프레임을 병합하기 위해 수행해야 할 작업을 설명하는 메타 데이터 필드가 있습니다. 각 프레임에 대해 프레임 오프셋, 크기 및 추출 방법을 얻으려는 속성 ID가 없습니다. 적절한 이미지 시퀀스를 얻으려면 각 프레임을 비트 맵으로 렌더링해야한다고 생각합니다. 매우 못생긴 세부 사항, GIF는 죽을 필요가있다.

+0

실제로 불쾌한 세부 사항. 이것은 [GIFS 중 하나]입니다. (http://upload.wikimedia.org/wikipedia/commons/5/50/Triple-Spiral-Labyrinth-animated.gif) Windows에서는 작동하지만 MonoMac에서는 작동하지 않습니다. [ 코드 붙여 넣기] (http://pastebin.com/Y6iUGDX9). 이 GIF의'times' var는 입니다. byte [20] = {75,000125000125000125000250000} '윈도우에서는 있지만 'byte [4] = {75,0,0,0}''이라고 표시됩니다. 앞서 언급했듯이 모든 GIF가 Windows에서 작동 했으므로 GIF의 단점 중 하나가 아닌 Mono의 문제일까요? – dsfgsho

+0

예, 바닥 매트 아래에서 청소할 수 없습니다. –

관련 문제