Wie entferne ich weiße Flecken aus dem GIF-Symbol in WPF?C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Wie entferne ich weiße Flecken aus dem GIF-Symbol in WPF?

Post by Anonymous »

Ich habe eine GIF-Klasse erstellt, die sich mit dem Rendern und Ausführen von GIF-Symboldateien in WPF befasst. Allerdings bekomme ich während der Animation immer wieder seltsame weiße Flecken auf dem GIF. Können Sie mir sagen, was ich tun kann, um GIF-Zulassung ohne diese Flecken zu erhalten?
Hier ist mein Code:

Code: Select all

public class Gif : Image
{
private bool _isInitialized;
private GifBitmapDecoder _decoder;
private int _frameIndex = 0;
private DispatcherTimer _timer;

public static readonly DependencyProperty GifSourceProperty =
DependencyProperty.Register(nameof(GifSource), typeof(string), typeof(Gif),
new PropertyMetadata(string.Empty, OnGifSourceChanged));

public static readonly DependencyProperty AutoStartProperty =
DependencyProperty.Register(nameof(AutoStart), typeof(bool), typeof(Gif),
new PropertyMetadata(true, OnAutoStartChanged));

public string GifSource
{
get { return (string)GetValue(GifSourceProperty); }
set { SetValue(GifSourceProperty, value); }
}

public bool AutoStart
{
get { return (bool)GetValue(AutoStartProperty); }
set { SetValue(AutoStartProperty, value); }
}

private static void OnGifSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Gif)d).Initialize();
}

private static void OnAutoStartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var gif = (Gif)d;

if ((bool)e.NewValue && gif.Visibility == Visibility.Visible)
{
gif.StartAnimation();
}
}

static Gif()
{
VisibilityProperty.OverrideMetadata(typeof(Gif), new FrameworkPropertyMetadata(VisibilityPropertyChanged));
}

private void Initialize()
{
if (string.IsNullOrEmpty(GifSource))
return;

_decoder = new GifBitmapDecoder(new Uri("pack://application:,,," + this.GifSource), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
this.Source = _decoder.Frames[0];
RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.HighQuality);

_timer = new DispatcherTimer();
_timer.Tick += Timer_Tick;

_isInitialized = true;

if (AutoStart && this.Visibility == Visibility.Visible)
StartAnimation();
}

private void StartTimerForFrame(int frameIndex)
{
int delay = 100; // default

try
{
var metadata = _decoder.Frames[frameIndex].Metadata as BitmapMetadata;

if (metadata != null)
{
object delayObj = metadata.GetQuery("/grctlext/Delay");

if (delayObj != null)
delay = ((ushort)delayObj) * 10;  // 1/100s → ms
}
}
catch { }

_timer.Interval = TimeSpan.FromMilliseconds(delay);
_timer.Start();
}

private void Timer_Tick(object sender, EventArgs e)
{
if (_decoder == null || _decoder.Frames.Count == 0)
return;

var frame = _decoder.Frames[_frameIndex];

var rtb = new RenderTargetBitmap(frame.PixelWidth, frame.PixelHeight, frame.DpiX, frame.DpiY, System.Windows.Media.PixelFormats.Pbgra32);
var dv = new DrawingVisual();

using (var ctx = dv.RenderOpen())
{
ctx.DrawImage(frame, new Rect(0, 0, frame.PixelWidth, frame.PixelHeight));
}

rtb.Render(dv);
this.Source = rtb;

_frameIndex = (_frameIndex + 1) % _decoder.Frames.Count;
StartTimerForFrame(_frameIndex);
}

private static void VisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var gif = (Gif)d;

if ((Visibility)e.NewValue == Visibility.Visible)
gif.StartAnimation();
else
gif.StopAnimation();
}

public void StartAnimation()
{
if (!_isInitialized)
Initialize();

GifAnimation(true);
}

public void StopAnimation()
{
GifAnimation(false);
}

private void GifAnimation(bool toStart)
{
if (_timer == null)
return;

if (toStart)
{
_frameIndex = 0;
StartTimerForFrame(_frameIndex);
}
else
{
_timer.Stop();
}
}

protected override Size MeasureOverride(Size availableSize)
{
if (this.Width > 0 && this.Height > 0)
return new Size(this.Width, this.Height);

return base.MeasureOverride(availableSize);
}
}
Siehe den Screenshot für die Ausgabe dieses Ansatzes:
Image

Image

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post