private void btnMorph_Click(object sender, EventArgs e) { if (pbStartImage.Image == null || pbEndImage.Image == null) { return; } // Get the parallel mode, the output mode, and query the user for the output path bool useParallelism = parallelProcessingModeToolStripMenuItem.Checked; OutputMode outputMode = aviOutputToolStripMenuItem.Checked ? OutputMode.Movie : OutputMode.ImageSequence; string outputPath = SelectOutputPath(outputMode); if (outputPath == null) { return; } // Grab UI data UiSettings settings; LinePairCollection lines; Bitmap startImage, endImage; PrepareUIDataForMorph(out settings, out lines, out startImage, out endImage); // Setup UI for run this.Text = "Parallel Morph - Running..."; pbMorphStatus.Visible = true; splitContainer1.Visible = false; menuStrip1.Enabled = false; btnCancel.Visible = true; btnCancel.Enabled = true; btnMorph.Enabled = false; pbInProgressMorph.Visible = true; _currentCancellationSource = new CancellationTokenSource(); var cancellationToken = _currentCancellationSource.Token; // Time how long the operation takes Stopwatch startTime = Stopwatch.StartNew(); // Create the morpher and launch the algorithm to run asynchronously _morpher = new ComputeMorph(settings, useParallelism, cancellationToken); _morpher.ProgressChanged += (ps, pe) => _uiThread.StartNew(() => pbMorphStatus.Value = pe.ProgressPercentage); Task.Factory.StartNew(() => { // Create an output writer based on whether we're writing to image files or to a movie file using (var tempImageWriter = outputMode == OutputMode.Movie ? (IImageWriter) new AviImageWriter(outputPath, settings.FramesPerSecond, startImage.Width, startImage.Height) : (IImageWriter) new JpgImageWriter(outputPath, "MorphFrame")) { // Also display every frame to the UI var imageWriter = new PassthroughImageWriter(tempImageWriter, bmp => { var clonedBmp = Utilities.CreateNewBitmapFrom(bmp); _uiThread.StartNew(() => { Image oldImage = pbInProgressMorph.Image; pbInProgressMorph.Image = clonedBmp; if (oldImage != null) { oldImage.Dispose(); } }); }); // Run the morph synchronously _morpher.Render(imageWriter, lines, startImage, endImage); } // When the morph completes, update the UI... }, cancellationToken).ContinueWith(t => { _morpher = null; btnMorph.Enabled = true; btnCancel.Visible = false; pbMorphStatus.Visible = false; splitContainer1.Visible = true; menuStrip1.Enabled = true; pbInProgressMorph.Visible = false; if (pbInProgressMorph.Image != null) { Image oldImage = pbInProgressMorph.Image; pbInProgressMorph.Image = null; oldImage.Dispose(); } this.Text = "Parallel Morph - " + t.Status + " - " + startTime.Elapsed.ToString(); if (t.IsFaulted) { MessageBox.Show(this, t.Exception.ToString(), "Morph Error"); } }, _uiThread.Scheduler); }
private void btnMorph_Click(object sender, EventArgs e) { if (pbStartImage.Image == null || pbEndImage.Image == null) return; // Get the parallel mode, the output mode, and query the user for the output path bool useParallelism = parallelProcessingModeToolStripMenuItem.Checked; OutputMode outputMode = aviOutputToolStripMenuItem.Checked ? OutputMode.Movie : OutputMode.ImageSequence; string outputPath = SelectOutputPath(outputMode); if (outputPath == null) return; // Grab UI data UiSettings settings; LinePairCollection lines; Bitmap startImage, endImage; PrepareUIDataForMorph(out settings, out lines, out startImage, out endImage); // Setup UI for run this.Text = "Parallel Morph - Running..."; pbMorphStatus.Visible = true; splitContainer1.Visible = false; menuStrip1.Enabled = false; btnCancel.Visible = true; btnCancel.Enabled = true; btnMorph.Enabled = false; pbInProgressMorph.Visible = true; _currentCancellationSource = new CancellationTokenSource(); var cancellationToken = _currentCancellationSource.Token; // Time how long the operation takes Stopwatch startTime = Stopwatch.StartNew(); // Create the morpher and launch the algorithm to run asynchronously _morpher = new ComputeMorph(settings, useParallelism, cancellationToken); _morpher.ProgressChanged += (ps, pe) => _uiThread.StartNew(() => pbMorphStatus.Value = pe.ProgressPercentage); Task.Factory.StartNew(() => { // Create an output writer based on whether we're writing to image files or to a movie file using (var tempImageWriter = outputMode == OutputMode.Movie ? (IImageWriter)new AviImageWriter(outputPath, settings.FramesPerSecond, startImage.Width, startImage.Height) : (IImageWriter)new JpgImageWriter(outputPath, "MorphFrame")) { // Also display every frame to the UI var imageWriter = new PassthroughImageWriter(tempImageWriter, bmp => { var clonedBmp = Utilities.CreateNewBitmapFrom(bmp); _uiThread.StartNew(() => { Image oldImage = pbInProgressMorph.Image; pbInProgressMorph.Image = clonedBmp; if (oldImage != null) oldImage.Dispose(); }); }); // Run the morph synchronously _morpher.Render(imageWriter, lines, startImage, endImage); } // When the morph completes, update the UI... }, cancellationToken).ContinueWith(t => { _morpher = null; btnMorph.Enabled = true; btnCancel.Visible = false; pbMorphStatus.Visible = false; splitContainer1.Visible = true; menuStrip1.Enabled = true; pbInProgressMorph.Visible = false; if (pbInProgressMorph.Image != null) { Image oldImage = pbInProgressMorph.Image; pbInProgressMorph.Image = null; oldImage.Dispose(); } this.Text = "Parallel Morph - " + t.Status + " - " + startTime.Elapsed.ToString(); if (t.IsFaulted) MessageBox.Show(this, t.Exception.ToString(), "Morph Error"); }, _uiThread.Scheduler); }