Flash Light Using Video Camera - c#

I found on the internet a tutorial (http://www.locked.nl) to turn Flash light on permanently. In the StartRecording() Method I am getting an exception when calling the Method twice. Also, How can I stop the recording ?? Thank you so much
I had these 2 classes.
VideoCamera Class:
public class VideoCamera
{
private object _videoCamera;
private PropertyInfo _videoCameraLampEnabledPropertyInfo;
private MethodInfo _videoCameraStartRecordingMethod;
private MethodInfo _videoCameraStopRecordingMethod;
private EventHandler _videoCameraInitialized;
public object InnerCameraObject
{
get { return _videoCamera; }
}
public bool LampEnabled
{
get { return (bool)_videoCameraLampEnabledPropertyInfo.GetGetMethod().Invoke(_videoCamera, new object[0]); }
set { _videoCameraLampEnabledPropertyInfo.GetSetMethod().Invoke(_videoCamera, new object[] { value }); }
}
public VideoCamera()
{
// Load the media extended assembly which contains the extended video camera object.
Assembly mediaExtendedAssembly = Assembly.Load("Microsoft.Phone.Media.Extended, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e");
// Get the camera source type (primary camera).
Type cameraSourceType = mediaExtendedAssembly.GetType("Microsoft.Phone.CameraSource");
FieldInfo field = cameraSourceType.GetField("PrimaryCamera");
object cameraSource = Enum.ToObject(cameraSourceType, (int)field.GetValue(cameraSourceType));
// Create the video camera object.
Type videoCameraType = mediaExtendedAssembly.GetType("Microsoft.Phone.VideoCamera");
ConstructorInfo videoCameraConstructor = videoCameraType.GetConstructor(new Type[] { cameraSourceType });
_videoCamera = videoCameraConstructor.Invoke(new object[] { cameraSource });
// Set the properties and methods.
_videoCameraLampEnabledPropertyInfo = videoCameraType.GetProperty("LampEnabled");
_videoCameraStartRecordingMethod = videoCameraType.GetMethod("StartRecording");
_videoCameraStopRecordingMethod = videoCameraType.GetMethod("StopRecording");
// Let the initialize event bubble through.
_videoCameraInitialized = new EventHandler(VideoCamera_Initialized);
MethodInfo addInitializedEventMethodInfo = videoCameraType.GetMethod("add_Initialized");
addInitializedEventMethodInfo.Invoke(_videoCamera, new object[] { _videoCameraInitialized });
}
/// <summary>
/// Occurs when the camera object has been initialized.
/// </summary>
public event EventHandler Initialized;
/// <summary>
/// Videoes the camera_ initialized.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="eventArgs">The event args.</param>
private void VideoCamera_Initialized(object sender, object eventArgs)
{
if (Initialized != null)
{
Initialized.Invoke(this, new EventArgs());
}
}
public bool IsRecording { get; private set; }
/// <summary>
/// Start recording.
/// </summary>
public void StartRecording()
{
_videoCameraStartRecordingMethod.Invoke(_videoCamera, new object[0]);
}
public void StopRecording()
{
}
}
}
and this class VideoCameraVisualizer
public class VideoCameraVisualizer : UserControl
{
private object _cameraVisualizer;
private MethodInfo _cameraVisualizerSetSourceMethod;
public VideoCameraVisualizer()
{
// Load the media extended assembly which contains the extended video camera object.
Assembly mediaExtendedAssembly = Assembly.Load("Microsoft.Phone.Media.Extended, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e");
// Get the camera source type (primary camera).
Type cameraVisualizerType = mediaExtendedAssembly.GetType("Microsoft.Phone.CameraVisualizer");
ConstructorInfo cameraVisualizerConstructor = cameraVisualizerType.GetConstructor(Type.EmptyTypes);
_cameraVisualizer = cameraVisualizerConstructor.Invoke(null);
// Set the properties and methods.
_cameraVisualizerSetSourceMethod = cameraVisualizerType.GetMethod("SetSource");
}
public void SetSource(VideoCamera camera)
{
// Invoke the set source method on the camera visualizer object.
_cameraVisualizerSetSourceMethod.Invoke(_cameraVisualizer, new object[] { camera.InnerCameraObject });
}
}
}
Now in the MainPage I had this Code that is giving an error.
private void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
// Check to see if the camera is available on the device.
if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary))
{
// Use standard camera on back of device.
videoCam = new VideoCamera();
// Event is fired when the video camera object has been initialized.
videoCam.Initialized += VideoCamera_Initialized;
// Add the photo camera to the video source
CameraVisualizer = new VideoCameraVisualizer();
CameraVisualizer.SetSource(videoCam);
}
else MessageBox.Show("No Flash supported for Your Device. Try Color Button");
}
private void VideoCamera_Initialized(object sender, EventArgs e)
{
videoCam.LampEnabled = true;
videoCam.StartRecording();
count++;
}
private void FlashButton_Click(object sender, RoutedEventArgs e)
{
if (count % 2 == 0)
{
videoCam.LampEnabled = true;
videoCam.StartRecording();
}
else
{
videoCam.LampEnabled = false;
videoCam.StopRecording();
}
count++;
}
}
}

Improve your google skills! ;)
have a read of this SO post - How to stop led torch/flashlight app using Reflection in Windows Phone 7
P.S. This is a nice blog post about the subject Using Cameras in Your Windows Phone Application

Related

how can I return value from show dialog form?

The main form:
fDocForm fDocForm = new fDocForm()
fDocForm.ShowDialog();
if(fDocForm.DialogResult!=null)
//use of id returned from dialog form
else
MessageBox.Show("null");
in the dialog form:
private void button1_Click(object sender, EventArgs e)
{
//insert sql command and returned id of inserted recored
DialogResult = DialogResult.OK;
this.Hide();
}
how could I return the id value from the dialog form to the main form?
One option is to pass data from child form to parent form using an event which is invoked when clicking a button on the child form, data is in a validate state invoke the event then set DialogResult to OK.
The following is a conceptual example where the main form opens a child form for adding a new item of type Note.
If all you need is a single property/value this will still work by changing the delegate signature OnAddNote.
Note class
public class Note : INotifyPropertyChanged
{
private string _title;
private string _content;
private int _id;
public int Id
{
get => _id;
set
{
_id = value;
OnPropertyChanged();
}
}
public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged();
}
}
public string Content
{
get => _content;
set
{
_content = value;
OnPropertyChanged();
}
}
public override string ToString() => Title;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Operations class
NewNote method is called from the child form Add button when data is validated
public class Operations
{
public delegate void OnAddNote(Note note);
public static event OnAddNote AddNote;
public static List<Note> NotesList = new List<Note>();
/// <summary>
/// Pass new Note to listeners
/// </summary>
/// <param name="note"></param>
public static void NewNote(Note note)
{
AddNote?.Invoke(note);
}
/// <summary>
/// Edit note, do some validation
/// </summary>
/// <param name="note"></param>
/// <returns></returns>
public static Note EditNote(Note note)
{
throw new NotImplementedException();
}
/// <summary>
/// Load mocked data, for a real application if persisting data use <see cref="LoadNotes"/>
/// </summary>
public static void Mocked()
{
NotesList.Add(new Note()
{
Title = "First",
Content = "My note"
});
}
/// <summary>
/// For a real application which persist your notes we would load from
/// - a database
/// - file (xml, json etc)
/// </summary>
/// <returns></returns>
public static List<Note> LoadNotes()
{
throw new NotImplementedException();
}
/// <summary>
/// Delete a note in <see cref="NotesList"/>
/// </summary>
/// <param name="note"></param>
public static void Delete(Note note)
{
throw new NotImplementedException();
}
public static Note FindByTitle(string title)
{
throw new NotImplementedException();
}
/// <summary>
/// Save data to the data source loaded from <see cref="LoadNotes"/>
/// </summary>
/// <returns>
/// Named value tuple
/// success - operation was successful
/// exception - if failed what was the cause
/// </returns>
public static (bool success, Exception exception) Save()
{
throw new NotImplementedException();
}
}
Child form
public partial class AddNoteForm : Form
{
public AddNoteForm()
{
InitializeComponent();
}
private void AddButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(TitleTextBox.Text) && !string.IsNullOrWhiteSpace(NoteTextBox.Text))
{
Operations.NewNote(new Note() {Title = TitleTextBox.Text, Content = NoteTextBox.Text});
DialogResult = DialogResult.OK;
}
else
{
DialogResult = DialogResult.Cancel;
}
}
}
Main form
public partial class Form1 : Form
{
private readonly BindingSource _bindingSource = new BindingSource();
public Form1()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
Operations.AddNote += OperationsOnAddNote;
Operations.Mocked();
_bindingSource.DataSource = Operations.NotesList;
NotesListBox.DataSource = _bindingSource;
ContentsTextBox.DataBindings.Add("Text", _bindingSource, "Content");
}
private void OperationsOnAddNote(Note note)
{
_bindingSource.Add(note);
NotesListBox.SelectedIndex = NotesListBox.Items.Count - 1;
}
private void AddButton_Click(object sender, EventArgs e)
{
var addForm = new AddNoteForm();
try
{
addForm.ShowDialog();
}
finally
{
addForm.Dispose();
}
}
}
Full source
You can store the id in a public property of the dialog, and the access that property from the main form.

SwipeRefreshLayout return bug

I'm using a SwipeRefeshLayout with a RecycleView inside.
This recycleView contains view-holders that have a click function that changes the display. This works fine until I refresh the view multiple times.
For example: If I refresh it 5 times, click on a viewholder, I will have to click 5 times on the return button to return to the recycleview fragment.
The code:
HomeFragment.cs:
private void HandleRefresh(object sender, EventArgs e)
{
try
{
page = 0;
adapter.clearMoments();
RefreshData(adapter, 0);
mySwipeRefreshLayout.Refreshing = false;
}
private async void RefreshData(MomentAdapterRV adapter, int page)
{
JsonValue json = await model.getMoments(page);
try
{
InitData(adapter, json, page);
}
private void InitData(MomentAdapterRV adapter, JsonValue json, int pageNum)
{
var myActivity = (MainActivity)this.Activity;
try
{
if (json.Count > 0)
{
for (var i = 0; i < json.Count; i++)
{
// Some code
adapter.addMoment(Moment moment)
}
// Some code
}
}
MomentAdapterRV.cs:
public MomentAdapterRV(Context context, List<Moment> items, MainActivity activity)
{
mItems = items;
mContext = context;
mActivity = activity;
cb = CommunityBuilderModel.Instance;
}
/// <summary>
/// This is the constuctor function of this adapter where the given class arguments (streamFragment, Moments) are being passed to the class variables.
/// </summary>
/// <param name="streamFragement"></param>
/// <param name="mItems"></param>
public MomentAdapterRV(StreamFragment streamFragement, List<Moment> mItems)
{
this.streamFragement = streamFragement;
this.mItems = mItems;
}
public void addMoment(Moment moment)
{
mItems.Add(moment);
NotifyDataSetChanged();
}
public void clearMoments()
{
mItems.Clear();
}
public override RecyclerView.ViewHolder
OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.MomentListItem, parent, false);
MomentViewHolder vh = new MomentViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
// Some code
vh.llMain.Click += (object sender, EventArgs e) =>
{
//Check if you don't get a negative position from the header.
if (holder.AdapterPosition >= 0)
{
// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = mActivity.FragmentManager.BeginTransaction();
MomentFragment aDifferentDetailsFrag = new MomentFragment();
// Some code
// Replace the fragment that is in the View fragment_container (if applicable).
fragmentTx.Replace(Resource.Id.frameLayout1, aDifferentDetailsFrag);
// Add the transaction to the back stack.
fragmentTx.AddToBackStack(null);
// Commit the transaction.
fragmentTx.Commit();
//Put Argument
aDifferentDetailsFrag.Arguments = utilBundle;
}
};
}
}
}
Your problem is that you assign the Click event in OnBindViewHolder and you never unsubscribe this click event.
So for each time you refresh your items in your RecyclerView, OnBindViewHolder is called. This will also happen if your list is longer than can be displayed on screen and you scroll up and down.
Instead you should assign the Click even in OnCreateViewHolder so it is only hooked up once, and not every time it is shown.

SelectedIndex on ComboBox to first item on data change

I'm learning UWP in VS2015 Community right now and having trouble with one section in regards to a ComboBox and could really use some help.
I'm writing a Bible app and have 3 ComboBoxes for Translation, Book, and Chapter. When I change the Book dropdown it should change the Chapter to 1. At least until I make a forward and back button for chapters, just covering the basics right now. When I change the Translation let's say from NIV to KJV it should change to the currently selected Book/Chapter in that translation.
I've preloaded the texts from XML and loaded them into an object called dataLoader. I'm doing selections on it via LINQ in the code below.
So right now I say something like:
private void DataLoader_Completed(object sender, EventArgs e)
{
dataLoaded = true;
cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName };
cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName };
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[0].Books[0].Chapters select new { c.Index };
cmb_Book.SelectedIndex = 0;
cmb_Translation.SelectedIndex = 0;
cmb_Chapter.SelectedIndex = 0;
}
private void translationChanged()
{
chapterChanged();
}
private void bookChanged()
{
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters select new { c.Index };
cmb_Chapter.SelectedIndex = 0;
}
private void chapterChanged()
{
textBlock_Verses.Text = dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters[cmb_Chapter.SelectedIndex].TextLineSeparated;
}
private void cmb_Translation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
translationChanged();
}
private void cmb_Book_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
bookChanged();
}
private void cmb_Chapter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
chapterChanged();
}
I'm getting errors back though on the first run that the index is out of range because at first the SelectedIndex of the translation is -1, if I run translation first it will give me an out of range on the book for SelectedIndex being -1.
I want the selected index changing to trigger the proper events but as you can see that's not going to work how it is now. Also the code is pretty messy, I've started looking a bit into Binding but there are a lot of hurdles like figuring out how to bind to a property that returns a LINQ result. I'm not sure how to move forward on this and definitely appreciate any help I can get.
Combobox can have no selection - selected item is null and this is how it's initialized, so before you set SelectedInexes all are null (this means that SelectedIndex == -1):
private void DataLoader_Completed(object sender, EventArgs e)
{
dataLoaded = true;
cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName };
cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName };
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[0].Books[0].Chapters select new { c.Index };
cmb_Book.SelectedIndex = 0; // <- you set here selected index for book
// which fires bookchanged even right away
// In that event cmb_Translation.SelectedIndex
// is still -1 which will surely throw exception
cmb_Translation.SelectedIndex = 0;
cmb_Chapter.SelectedIndex = 0;
}
You probably should put some check-ups if values are properly set before using them. Also think if there is a chance when there is no selection state.
private void bookChanged()
{
if (cmb_Translation.SelectedIndex >= 0)
{
cmb_Chapter.ItemsSource = from c in dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters select new { c.Index };
cmb_Chapter.SelectedIndex = 0;
}
}
There is one hiccup with this - you will have to launch bookchanged() at the endo of DataLoader_Completed manually, as it won't process before, due to -1.
Here's the solution I came to that works, although I think maybe a better solution could have been achieved using Binding to properties I've created, some feedback on improvements could always be helpful from a design perspective. What I did essentially was create an UpdateChapterText Boolean property that when set to false won't process my SelectedIndex change events, but will still allow me to update underlying data sources and change the SelectedIndex on the fly, that way I can process events in one go, otherwise it might be fire multiple events to update the underlying data sources. I needed to be able to do this because for the chapter text view it relies on both the translation and book selected indexes to be set, but the default behavior only allows one or the other to be set before events process, which becomes unsolvable at least I think for now unless you turn off events processing I found.
/// <summary>
/// This is a helper property for setting the Translation SelectedIndex
/// </summary>
private int TranslationIndex
{
get
{
return cmb_Translation.SelectedIndex;
}
set
{
cmb_Translation.SelectedIndex = value;
}
}
/// <summary>
/// This is a helper property for setting the Book SelectedIndex
/// </summary>
private int BookIndex
{
get
{
return cmb_Book.SelectedIndex;
}
set
{
cmb_Book.SelectedIndex = value;
}
}
/// <summary>
/// This is a helper property for setting the Chapter SelectedIndex
/// </summary>
private int ChapterIndex
{
get
{
return cmb_Chapter.SelectedIndex;
}
set
{
cmb_Chapter.SelectedIndex = value;
}
}
/// <summary>
/// Retrieves the currently selected Chapter listing
/// </summary>
public IEnumerable<ChapterIndex> CurrentChapters
{
get
{
return from c in dataLoader.Translations[TranslationIndex].Books[BookIndex].Chapters select new ChapterIndex { Index = c.Index };
}
}
/// <summary>
/// Retrieves Genesis in the first loaded translation
/// </summary>
public IEnumerable<ChapterIndex> Genesis
{
get
{
return from c in dataLoader.Translations[0].Books[0].Chapters select new ChapterIndex { Index = c.Index };
}
}
public IEnumerable<BookNames> CurrentBooks
{
get
{
return from b in dataLoader.Translations[TranslationIndex].Books select new BookNames { BookName = b.BookName };
}
}
/// <summary>
/// Allows events to process on ComboBoxes and Back/Forward Buttons
/// to change Chapters, you usually don't want to do this lots of
/// times in one second if changing the Translation/Book/Chapter
/// all at one time so you may set it to false first, update your
/// variables, and then set it back to true so updating events will
/// process correctly.
/// </summary>
public bool UpdateChapterText { get; set; }
/// <summary>
/// The DataLoader object loads up the various Bible translation texts
/// </summary>
TheBible.Model.DataLoader.DataLoader dataLoader;
public MainPage()
{
this.InitializeComponent();
dataLoader = new Model.DataLoader.DataLoader();
dataLoader.Completed += DataLoader_Completed;
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
}
private void DataLoader_Completed(object sender, EventArgs e)
{
UpdateChapterText = false;
cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName };
cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName };
cmb_Chapter.ItemsSource = Genesis;
cmb_Translation.SelectedIndex = 0;
cmb_Book.SelectedIndex = 0;
UpdateChapterText = true;
cmb_Chapter.SelectedIndex = 0;
}
private void translationChanged()
{
chapterChanged();
}
private void bookChanged()
{
UpdateChapterText = false;
cmb_Chapter.ItemsSource = CurrentChapters;
UpdateChapterText = true;
cmb_Chapter.SelectedIndex = 0;
}
private void chapterChanged()
{
textBlock_Verses.Text = dataLoader.Translations[TranslationIndex].Books[BookIndex].Chapters[ChapterIndex].TextLineSeparated;
}
private void decrementChapter()
{
UpdateChapterText = false;
if (this.cmb_Chapter.SelectedIndex == 0)
{
if (this.cmb_Book.SelectedIndex > 0)
{
this.cmb_Book.SelectedIndex--;
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex = CurrentChapters.Count() - 1;
}
}
else
{
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex--;
}
UpdateChapterText = true;
}
private void incrementChapter()
{
UpdateChapterText = false;
if (this.cmb_Chapter.SelectedIndex == this.cmb_Chapter.Items.Count - 1)
{
if (this.cmb_Book.SelectedIndex < this.cmb_Book.Items.Count - 1)
{
this.cmb_Book.SelectedIndex++;
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex = 0;
}
}
else
{
UpdateChapterText = true;
this.cmb_Chapter.SelectedIndex++;
}
UpdateChapterText = true;
}
private void cmb_Translation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UpdateChapterText)
translationChanged();
}
private void cmb_Book_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UpdateChapterText)
bookChanged();
}
private void cmb_Chapter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UpdateChapterText)
chapterChanged();
}
private void btn_Forward_Click(object sender, RoutedEventArgs e)
{
incrementChapter();
}
private void btn_Back_Click(object sender, RoutedEventArgs e)
{
decrementChapter();
}
private void btn_FullScreen_Click(object sender, RoutedEventArgs e)
{
var view = ApplicationView.GetForCurrentView();
if (view.IsFullScreenMode)
{
sym_FullScreen.Symbol = Symbol.FullScreen;
view.ExitFullScreenMode();
}
else
{
sym_FullScreen.Symbol = Symbol.BackToWindow;
view.TryEnterFullScreenMode();
}
}

xbox 360 kinect beam angle issue with property change

trying to get the beam angle in a C# wpf and there is an exception being thrown on the If PropertyChange. Does anyone have an example of this project, I can supply more information if needed. I am trying to get the mics change the property but instead it is throwing an exception
InitializeComponent();
//Beam Angle Code
this.DataContext = this.Rect;
this.Loaded += delegate { ListenForBeamChanges(); };
}
private KinectAudioSource CreateAudioSource()
{
var source = KinectSensor.KinectSensors[0].AudioSource;
source.NoiseSuppression = true;
source.AutomaticGainControlEnabled = true;
source.BeamAngleMode = BeamAngleMode.Adaptive;
return source;
}
private KinectAudioSource audioSource;
private void ListenForBeamChanges()
{
KinectSensor.KinectSensors[0].Start();
audioSource = CreateAudioSource();
audioSource.BeamAngleChanged += audioSource_BeamChanged;
audioSource.Start();
}
public double _beamAngle;
public double BeamAngle
{
get { return _beamAngle; }
set
{
_beamAngle = value;
OnPropertyChanged("BeamAngle");
}
}
void audioSource_BeamChanged(object sender, BeamAngleChangedEventArgs e)
{
BeamAngle = e.Angle * -1;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
see http://kinectaudioposition.codeplex.com
copying sample usage code from http://channel9.msdn.com/coding4fun/kinect/Kinect-Audio-Positioning
/// <summary>
/// Event handler to care Window loaded
/// Construct KinectMicArray and draw contents
/// </summary>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
kinectMic = new KinectMicArray();
kinectMic.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(kinectMic_PropertyChanged);
DrawContents();
}
/// <summary>
/// Event handler to care KinectMicArray property changed
/// Showing angles as number for debug
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void kinectMic_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
KinectMicArray ka = sender as KinectMicArray;
this.myLabel.Content = string.Format("Beam = {0:F}; Source = {1:F}; ", ka.BeamAngleProperty, ka.SourceAngleProperty);
}

GIF animation CPU consumption problem in C#!

I have made a GIF Animation user control which loads gif animations and have created about 30 of them in my project each animating a GIF. The problem is that when I check my CPU usage it is about 70%+!!! I'm sure something is wrong with this!
Please help me. Here is the code of that GIF Animator control:
public class AnimatedImage : System.Windows.Controls.Image
{
private BitmapSource[] _BitmapSources = null;
private int _nCurrentFrame=0;
private bool _bIsAnimating=false;
public bool IsAnimating
{
get { return _bIsAnimating; }
}
static AnimatedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimatedImage), new FrameworkPropertyMetadata(typeof(AnimatedImage)));
}
public Bitmap AnimatedBitmap
{
get { return (Bitmap)GetValue(AnimatedBitmapProperty); }
set { StopAnimate(); SetValue(AnimatedBitmapProperty, value); }
}
/// <summary>
/// Identifies the Value dependency property.
/// </summary>
public static readonly DependencyProperty AnimatedBitmapProperty =
DependencyProperty.Register(
"AnimatedBitmap", typeof(Bitmap), typeof(AnimatedImage),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnAnimatedBitmapChanged)));
private static void OnAnimatedBitmapChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
AnimatedImage control = (AnimatedImage)obj;
control.UpdateAnimatedBitmap();
RoutedPropertyChangedEventArgs<Bitmap> e = new RoutedPropertyChangedEventArgs<Bitmap>(
(Bitmap)args.OldValue, (Bitmap)args.NewValue, AnimatedBitmapChangedEvent);
control.OnAnimatedBitmapChanged(e);
}
/// <summary>
/// Identifies the ValueChanged routed event.
/// </summary>
public static readonly RoutedEvent AnimatedBitmapChangedEvent = EventManager.RegisterRoutedEvent(
"AnimatedBitmapChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<Bitmap>), typeof(AnimatedImage));
/// <summary>
/// Occurs when the Value property changes.
/// </summary>
public event RoutedPropertyChangedEventHandler<Bitmap> AnimatedBitmapChanged
{
add { AddHandler(AnimatedBitmapChangedEvent, value); }
remove { RemoveHandler(AnimatedBitmapChangedEvent, value); }
}
/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="args">Arguments associated with the ValueChanged event.</param>
protected virtual void OnAnimatedBitmapChanged(RoutedPropertyChangedEventArgs<Bitmap> args)
{
RaiseEvent(args);
}
private void UpdateAnimatedBitmap()
{
int nTimeFrames = AnimatedBitmap.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
_nCurrentFrame = 0;
if (nTimeFrames > 0)
{
_BitmapSources = new BitmapSource[nTimeFrames];
for (int i = 0; i < nTimeFrames; i++)
{
AnimatedBitmap.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time, i);
Bitmap bitmap = new Bitmap(AnimatedBitmap);
bitmap.MakeTransparent();
_BitmapSources[i] = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
}
StartAnimate();
}
}
private delegate void VoidDelegate();
private void OnFrameChanged(object o, EventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Render, new VoidDelegate(delegate { ChangeSource(); }));
}
void ChangeSource()
{
Source = _BitmapSources[_nCurrentFrame++];
_nCurrentFrame = _nCurrentFrame % _BitmapSources.Length;
ImageAnimator.UpdateFrames();
}
public void StopAnimate()
{
if (_bIsAnimating)
{
ImageAnimator.StopAnimate(AnimatedBitmap, new EventHandler(this.OnFrameChanged));
_bIsAnimating = false;
}
}
public void StartAnimate()
{
if (!_bIsAnimating)
{
ImageAnimator.Animate(AnimatedBitmap, new EventHandler(this.OnFrameChanged));
_bIsAnimating = true;
}
}
}
}
Give this one a shot. We've used it in our application and I haven't notice any weird memory consumption.

Categories