private void SaveResults() { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "PNG file (*.png)|*.png"; if (sfd.ShowDialog() == DialogResult.OK) { int counter = 0; int maxSize = 100; int widthMargin = 30; int heightMargin = 30; int rowWidth = 5; Bitmap resultImage = null; Graphics g = null; int lastFrame = data.CurrentFrame; bool isPlaying = videoTimer.Enabled; data.CurrentFrame = 0; TransitionData[] cuts = cutDetection.GetTransitions(); TransitionData[] fades = fadeDetection.GetTransitions(); var all = cuts.Union(fades).OrderBy(t => t.StartFrame); foreach (TransitionData transition in all) { bool isCut = true; int frameIndex = transition.StartFrame + 2; if (frameIndex >= data.FrameCount) { frameIndex = data.FrameCount - 2; } if (transition.StartFrame != transition.EndFrame) { frameIndex = (transition.StartFrame + transition.EndFrame) / 2; isCut = false; } data.CurrentFrame = frameIndex; ImageData frame = data.GetNextFrame(); int column = counter % rowWidth; int row = counter / rowWidth; int width = frame.Image.Width > maxSize ? maxSize : frame.Image.Width; int height = frame.Image.Height > maxSize ? maxSize : frame.Image.Height; widthMargin = (int)(width * 0.3); heightMargin = (int)(height * 0.3); int rowHeight = (all.Count() / rowWidth) + 1; if (resultImage == null) { resultImage = new Bitmap(width * rowWidth + (rowWidth + 1) * widthMargin, rowHeight * height + (rowHeight + 1) * heightMargin); g = Graphics.FromImage(resultImage); g.TextRenderingHint = TextRenderingHint.AntiAlias; } int left = widthMargin + column * (width + widthMargin); int top = heightMargin + row * (height + heightMargin); g.DrawImage(frame.Image, left, top, width, height); string transitionType = "Cut"; if (!isCut) { transitionType = "Fade"; } transitionType += " - " + frameIndex.ToString(); Font font = new Font("Segoe UI", 11, FontStyle.Regular, GraphicsUnit.Pixel); SizeF sizeType = g.MeasureString(transitionType, font); g.DrawString(transitionType, font, Brushes.Black, left + width / 2f - sizeType.Width / 2f, top + height + (heightMargin / 2f) - (sizeType.Height / 2)); counter++; } g.Dispose(); resultImage.Save(sfd.FileName, ImageFormat.Png); resultImage.Dispose(); if (isPlaying) { data.CurrentFrame = lastFrame; } } }