Fix #78: Use Gif Disposal flag in the correct way

This commit is contained in:
Paddy Xu
2017-10-05 20:54:33 +03:00
parent abd69a2acd
commit 333857ff81

View File

@@ -34,13 +34,12 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
var clock = TimeSpan.Zero; var clock = TimeSpan.Zero;
BitmapSource prevFrame = null; BitmapSource prevFrame = null;
FrameInfo prevInfo = null; FrameInfo prevInfo = null;
BitmapSource prevprevFrame = null;
foreach (var rawFrame in decoder.Frames) foreach (var rawFrame in decoder.Frames)
{ {
var info = GetFrameInfo(rawFrame); var info = GetFrameInfo(rawFrame);
var frame = MakeFrame( var frame = MakeFrame(decoder.Frames[0], rawFrame, info, prevFrame, prevInfo, prevprevFrame);
decoder.Frames[0], prevprevFrame = prevFrame;
rawFrame, info,
prevFrame, prevInfo);
prevFrame = frame; prevFrame = frame;
prevInfo = info; prevInfo = info;
@@ -57,16 +56,29 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
private static BitmapSource MakeFrame( private static BitmapSource MakeFrame(
BitmapSource fullImage, BitmapSource fullImage,
BitmapSource rawFrame, FrameInfo frameInfo, BitmapSource rawFrame, FrameInfo frameInfo,
BitmapSource previousFrame, FrameInfo previousFrameInfo) BitmapSource previousFrame, FrameInfo previousFrameInfo,
BitmapSource previouspreviousFrame)
{ {
var visual = new DrawingVisual(); var visual = new DrawingVisual();
using (var context = visual.RenderOpen()) using (var context = visual.RenderOpen())
{ {
if (previousFrameInfo != null && previousFrame != null && if (previousFrameInfo != null && previousFrame != null)
previousFrameInfo.DisposalMethod == FrameDisposalMethod.Combine)
{ {
var fullRect = new Rect(0, 0, fullImage.PixelWidth, fullImage.PixelHeight); var fullRect = new Rect(0, 0, fullImage.PixelWidth, fullImage.PixelHeight);
context.DrawImage(previousFrame, fullRect);
switch (previousFrameInfo.DisposalMethod)
{
case FrameDisposalMethod.Unspecified:
case FrameDisposalMethod.Combine:
context.DrawImage(previousFrame, fullRect);
break;
case FrameDisposalMethod.RestorePrevious:
if (previouspreviousFrame != null)
context.DrawImage(previouspreviousFrame, fullRect);
break;
case FrameDisposalMethod.RestoreBackground:
break;
}
} }
context.DrawImage(rawFrame, frameInfo.Rect); context.DrawImage(rawFrame, frameInfo.Rect);
@@ -84,7 +96,7 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
var frameInfo = new FrameInfo var frameInfo = new FrameInfo
{ {
Delay = TimeSpan.FromMilliseconds(100), Delay = TimeSpan.FromMilliseconds(100),
DisposalMethod = FrameDisposalMethod.Replace, DisposalMethod = FrameDisposalMethod.Unspecified,
Width = frame.PixelWidth, Width = frame.PixelWidth,
Height = frame.PixelHeight, Height = frame.PixelHeight,
Left = 0, Left = 0,
@@ -152,7 +164,7 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
private enum FrameDisposalMethod private enum FrameDisposalMethod
{ {
Replace = 0, Unspecified = 0,
Combine = 1, Combine = 1,
RestoreBackground = 2, RestoreBackground = 2,
RestorePrevious = 3 RestorePrevious = 3