/// <summary> /// Rendering method executed in a background thread. /// </summary> protected virtual void SlideRendering() { const int minDisplayTime = 3000; const int maxDisplayTime = 13000; const int renderThreadSleepTime = 30; // Sleep time of the rendering thread in milliseconds Random rnd = new Random(); Bitmap renderingImage = new Bitmap(this.renderedImageSize.Width, this.renderedImageSize.Height); using (Graphics graphics = Graphics.FromImage(renderingImage)) { graphics.FillRectangle(new SolidBrush(Color.Black), 0, 0, renderingImage.Width, renderingImage.Height); } try { while (true) { try { // Retrieve next slide show item SlideShowItem nextItem = this.configuration.Next(); int realDisplayTime = nextItem.DisplayTime; // Check next slide show item if (nextItem.DisplayImage == null) { throw new InvalidOperationException("ISlideShowConfiguration.Next: SlideShowItem.DisplayImage is null"); } if (nextItem.DisplayImage.Width < 1000 || nextItem.DisplayImage.Height < 1000) { throw new InvalidOperationException("ISlideShowConfiguration.Next: SlideShowItem.DisplayImage: minimal image size is 1000x1000 px"); } if (realDisplayTime < minDisplayTime) { realDisplayTime = minDisplayTime; } if (realDisplayTime > maxDisplayTime) { realDisplayTime = maxDisplayTime; } int zoom = 0; while (zoom == 0) { zoom = rnd.Next(-1, 2); } Rectangle renderingRectangle = default(Rectangle); double ratio = (double)nextItem.DisplayImage.Width / (double)nextItem.DisplayImage.Height; if (zoom > 0) { // zoom in renderingRectangle.Width = rnd.Next((int)(nextItem.DisplayImage.Width * 0.75) + 50, nextItem.DisplayImage.Width + 1); renderingRectangle.Height = (int)Math.Round(renderingRectangle.Width / ratio, 0); renderingRectangle.X = rnd.Next(0, nextItem.DisplayImage.Width - renderingRectangle.Width + 1); renderingRectangle.Y = rnd.Next(0, nextItem.DisplayImage.Height - renderingRectangle.Height + 1); } else if (zoom < 0) { // zoom out renderingRectangle.Height = rnd.Next((int)(nextItem.DisplayImage.Height * 0.5) + 50, nextItem.DisplayImage.Height - 300 + 1); renderingRectangle.Width = (int)Math.Round(renderingRectangle.Height * ratio, 0); renderingRectangle.X = rnd.Next(150, nextItem.DisplayImage.Width - renderingRectangle.Width - 150 + 1); renderingRectangle.Y = rnd.Next(150, nextItem.DisplayImage.Height - renderingRectangle.Height - 150 + 1); } long i = 0; Stopwatch watch = new Stopwatch(); watch.Start(); while (true) { renderingRectangle.X = renderingRectangle.X + zoom; renderingRectangle.Y = renderingRectangle.Y + zoom; renderingRectangle.Width = renderingRectangle.Width - (2 * zoom); renderingRectangle.Height = renderingRectangle.Height - (2 * zoom); using (Graphics graphics = Graphics.FromImage(renderingImage)) { // Security fallback if rendering is too fast if (i < 150) { // Fade in: 10 steps if (i < 10) { ColorMatrix matrix = new ColorMatrix(); matrix.Matrix33 = 1f / (float)(10 - i); // Opacity ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); graphics.DrawImage( nextItem.DisplayImage, new Rectangle(0, 0, renderingImage.Width, renderingImage.Height), renderingRectangle.Left, renderingRectangle.Top, renderingRectangle.Width, renderingRectangle.Height, GraphicsUnit.Pixel, imageAttributes); } else { graphics.DrawImage( nextItem.DisplayImage, new Rectangle(0, 0, renderingImage.Width, renderingImage.Height), renderingRectangle, GraphicsUnit.Pixel); } } } this.ImageRendered?.Invoke(this, new ImageEventArgs(renderingImage)); i++; Thread.Sleep(renderThreadSleepTime); if (watch.ElapsedMilliseconds > realDisplayTime) { break; } } Debug.WriteLine("END-END-END"); watch.Stop(); GC.Collect(); } catch (ThreadAbortException) { throw; } catch (Exception ex) { this.Error?.Invoke(this, new RenderingErrorEventArgs(ex)); } } } catch (ThreadAbortException) { Thread.ResetAbort(); } }
/// <summary> /// Rendering method executed in a background thread. /// </summary> protected virtual void SlideRendering() { const int slideChangeTime = 1000; // The time in milliseconds used for the fade in of the new image const int slideChangeSteps = 50; // The number of fade in steps performed Bitmap renderingImage = new Bitmap(this.renderedImageSize.Width, this.renderedImageSize.Height); using (Graphics graphics = Graphics.FromImage(renderingImage)) { graphics.FillRectangle(new SolidBrush(Color.Black), 0, 0, renderingImage.Width, renderingImage.Height); } try { while (true) { try { // Retrieve next slide show item SlideShowItem nextItem = this.configuration.Next(); int realDisplayTime = nextItem.DisplayTime; // Check next slide show item if (nextItem.DisplayImage == null) { throw new InvalidOperationException("ISlideShowConfiguration.Next: SlideShowItem.DisplayImage is null"); } if (realDisplayTime < 1000) { realDisplayTime = 1000; } for (int i = 0; i < slideChangeSteps; i++) { using (Graphics graphics = Graphics.FromImage(renderingImage)) { ColorMatrix matrix = new ColorMatrix(); matrix.Matrix33 = 1f / (float)(slideChangeSteps - i); // Opacity ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); graphics.DrawImage( nextItem.DisplayImage, new Rectangle(0, 0, renderingImage.Width, renderingImage.Height), 0, 0, nextItem.DisplayImage.Width, nextItem.DisplayImage.Height, GraphicsUnit.Pixel, imageAttributes); } Thread.Sleep((int)(slideChangeTime / slideChangeSteps)); this.ImageRendered?.Invoke(this, new ImageEventArgs(renderingImage)); } GC.Collect(); Thread.Sleep(realDisplayTime); } catch (ThreadAbortException) { throw; } catch (Exception ex) { this.Error?.Invoke(this, new RenderingErrorEventArgs(ex)); } } } catch (ThreadAbortException) { Thread.ResetAbort(); } }