Как убрать появление белых пятен на значке GIF в wpf?C#

Место общения программистов C#
Ответить
Anonymous
 Как убрать появление белых пятен на значке GIF в wpf?

Сообщение Anonymous »

Я создал класс gif, который занимается рендерингом и запуском файлов значков gif в wpf. Тем не менее, во время анимации на гифке продолжают появляться странные белые пятна. Можете ли вы сказать мне, что я могу сделать, чтобы получить разрешение gif без этих мест?
Вот мой код:

Код: Выделить всё

    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);
}
}
Результат этого подхода см. на изображении.
Изображение

Изображение


Подробнее здесь: https://stackoverflow.com/questions/797 ... con-in-wpf
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»