검색결과 리스트
글
Animated Image
(움직이는 이미지)
Intro
WPF 에서 많이 사용하는 ImageSource 의 경우, AnimatedImage 를 지원하지 않습니다. 소위 말하는 '움짤'을 표시할 수 없다라는 것이죠. 고정된 이미지로 보여집니다. 현재로서는 이를 지원하기 위해서 구현을 해 주어야 하지요.
Content
구현하는 방법은 대략 이렇습니다. BitmapDecoder 를 이용하여 Image 의 Frame 들을 얻어옵니다. 여기서 Frame 이란 Animated Image 의 각 장면들을 말합니다. 이렇게 얻은 Frame 을 일정 주기마다 화면에 출력합니다. 간단하죠? 코드는 아래와 같습니다.
public class AnimatedImage : Image
{
BitmapDecoder decoder = null;
private int Count = 0;
private System.Timers.Timer Timer = new System.Timers.Timer();
private object TimerLock = new object();
public double Interval { get { return this.Timer.Interval; } set { this.Timer.Interval = value; } }
public bool IsPlaying { get; set; }
public AnimatedImage()
: base() {
this.IsPlaying = false;
this.Interval = 100;
this.Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
}
//-------------------------
// Image 변경되었을 경우
//-------------------------
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) {
if (e.Property.Name == "Source") {
if (e.NewValue != null &&
(e.OldValue == null || (e.NewValue.ToString() != e.OldValue.ToString()))) {
this.Stop();
try {
decoder = new BitmapDecoder(new Uri(e.NewValue.ToString()),
BitmapCreateOptions.None, BitmapCacheOption.None);
} catch { }
this.Start();
}
}
base.OnPropertyChanged(e);
}
//-------------------------
// Start Animation
//-------------------------
private void Start() {
lock (TimerLock) {
if (this.decoder != null && this.decoder.Frames.Count > 1) {
if (this.IsPlaying == false) {
this.IsPlaying = true;
this.Timer.Start();
}
}
}
}
//-------------------------
// Stop Animation
//-------------------------
private void Stop() {
lock (TimerLock) {
this.IsPlaying = false;
this.Timer.Stop();
}
}
//-------------------------
// Timer Procedure
//-------------------------
void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
this.Dispatcher.BeginInvoke(new Action(delegate {
Count = ++Count % decoder.Frames.Count;
this.Source = decoder.Frames[Count];
this.InvalidateArrange();
}), null);
}
}
이 코드에는 해결해야 하는 문제가 조금 남아 있습니다.
1. Image 의 Source 에 이미지의 uri 정보가 있어야만 동작합니다.
- Image 에 Stream 을 통해서 만든 ImageSource 나 BitmapImage 등이 들어가면, BitmapDecoder 를 생성하지 못합니다.
- 즉, Source 에 들어오는 Object Type 별로 BitmapDecoder 를 생성하는 루틴을 추가해야 합니다.
2. WPF 의 고질적인 Image 에 Uri 가 들어갈 경우, 이미지 파일 락(File Lock)이 걸립니다.
- WPF 에서 ImageSource 를 Uri 를 통해 만들었을 때, File Handle 을 Release 하는 방법을 적용하면 됩니다.
- 이는 기존에 WPF Image 에 존재하는 문제입니다.
사용법은 다음과 같습니다.
<font face="Arial Black"><AnimatedImage Source="C:\crystalcube.gif" Interval="100"/> </font>
Interval 에 따라서 Animation 의 속도가 변경됩니다. 보통 100 정도면 적당하더군요.
Result
혹 위에 언급한 두가지 문제를 해결하는 방법을 아시면~ 공유 부탁합니다 ^-^
'Microsoft > WPF' 카테고리의 다른 글
TypeConverter (0) | 2014.05.12 |
---|---|
XAML 의 문법구조 (0) | 2014.05.12 |
xaml 과 cs 파일의 관계 (1) | 2014.05.08 |
WPF 기본 동작구조 (0) | 2014.05.08 |
WPF 3D Tutorial (7) | 2011.04.09 |
RECENT COMMENT