/// <summary> /// Dumps the Column/Rows determination (based on aspect ratio) Plot. /// </summary> /// <param name="filename">name of the image file to write to.</param> /// <param name="plotThresholds">if set to <c>true</c> plot threshold info.</param> private void DumpColRowsPlot(string filename, bool plotThresholds) { bool detailsPage; int nThumbs, nCols, nRows; double crossoverThreshold; filename = System.IO.Path.GetFileNameWithoutExtension (filename) + ".png"; if (System.IO.File.Exists (filename)) { Console.Write ("'{0}' already exists. Overwrite (Y/N) [N]?", filename); string answer = Console.ReadLine (); answer = answer.Trim ().ToLower (); if (answer != "y" && answer != "yes") { Console.Write ("Aborting operation."); return; } } if (_tnSettings.Interval.TotalSeconds > 0) { detailsPage = true; nThumbs = _tnSettings.DetailThumbs; nCols = _tnSettings.DetailColumns; nRows = _tnSettings.DetailRows; crossoverThreshold = _tnSettings.DetailThreshold; } else { detailsPage = false; nThumbs = _tnSettings.OverviewThumbs; nCols = _tnSettings.OverviewColumns; nRows = _tnSettings.OverviewRows; crossoverThreshold = _tnSettings.OverviewThreshold; } THelper.Information (""); THelper.Information ("Dumping Column/Rows Determination Plot"); THelper.Information ("Page: {0} {1}x{2} ({3:F2}:1)", detailsPage ? "Detail" : "Overview", _tnSettings.Width, _tnSettings.Height, _tnSettings.AspectRatio); THelper.Information ("Layout Mode: {0}", _tnSettings.LayoutMode); if (_tnSettings.LayoutMode == ThumbnailSettings.LayoutModes.Auto) THelper.Information ("Threshold: {0:F2}", crossoverThreshold); if (_tnSettings.LayoutMode == ThumbnailSettings.LayoutModes.Actual) { THelper.Information ("Actual: {1}x{2}", nCols, nRows); } else { THelper.Information ("RC Optimization: {0}", _tnSettings.RCOptimization); THelper.Information ("Max RC Opt Steps: {0}", _tnSettings.MaxOptimizationSteps); THelper.Information ("Desired: {0} thumbs", nThumbs); THelper.Information ("Minimum: {0} columns, {1} rows", _tnSettings.MinColumns, _tnSettings.MinRows); } THelper.Information (""); System.Drawing.Font titleFont = new System.Drawing.Font ("Ariel", 24, System.Drawing.FontStyle.Bold); System.Drawing.Font subTitleFont = new System.Drawing.Font ("Ariel", 13, System.Drawing.FontStyle.Bold); System.Drawing.Font axisLabelFont = new System.Drawing.Font ("Ariel", 20, System.Drawing.FontStyle.Bold); System.Drawing.Font axisFont = new System.Drawing.Font ("Ariel", 12, System.Drawing.FontStyle.Bold); System.Drawing.Font annotationFont = new System.Drawing.Font ("Ariel", 10, System.Drawing.FontStyle.Regular); System.Drawing.Font annotationItFont = new System.Drawing.Font ("Ariel", 10, System.Drawing.FontStyle.Italic); Charting.Chart chart = new Charting.Chart (); Charting.ChartArea chartArea = chart.ChartAreas.Add ("Wasted"); Charting.Legend legend = new Charting.Legend ("Wasted"); legend.DockedToChartArea = "Wasted"; legend.Font = axisFont; legend.Docking = Charting.Docking.Bottom; legend.Alignment = System.Drawing.StringAlignment.Far; legend.LegendStyle = Charting.LegendStyle.Column; chart.Legends.Add (legend); Charting.LabelStyle labelStyle1 = new Charting.LabelStyle(); labelStyle1.Font = axisFont; Charting.LabelStyle labelStyle2 = new Charting.LabelStyle (); labelStyle2.Font = axisFont; Charting.LabelStyle labelStyle3 = new Charting.LabelStyle (); labelStyle3.Font = axisFont; chart.BackColor = System.Drawing.Color.Wheat; chartArea.BorderWidth = 3; chartArea.BorderDashStyle = Charting.ChartDashStyle.Solid; //chartArea.BorderColor = System.Drawing.Color.Violet; legend.BackColor = System.Drawing.Color.Wheat; string titleStr = "Optimum Number of Columns & Rows"; if (plotThresholds) titleStr += "\nUsing % Wasted Thumbnail Width & Height"; Charting.Title title = chart.Titles.Add (titleStr); title.Font = titleFont; //subTitle.DockingOffset = -2; Charting.TextAnnotation desired = new Charting.TextAnnotation (); desired.Font = subTitleFont; switch (_tnSettings.LayoutMode) { case ThumbnailSettings.LayoutModes.Auto: chartArea.BackColor = System.Drawing.Color.Beige; desired.Text = String.Format ( "{0} Cols or Rows; Min {1} Cols, {2} Rows; {3} Max Opt Steps", nThumbs, _tnSettings.MinColumns, _tnSettings.MinRows, _tnSettings.MaxOptimizationSteps); break; case ThumbnailSettings.LayoutModes.Actual: chartArea.BackColor = System.Drawing.Color.Ivory; desired.Text = String.Format ("{0} Columns and {1} Rows", nCols, nRows); break; case ThumbnailSettings.LayoutModes.RowPriority: chartArea.BackColor = System.Drawing.Color.Beige; desired.Text = String.Format ( "{0} Rows; Min {1} Columns; {2} Max Opt Steps", nThumbs, _tnSettings.MinColumns, _tnSettings.MaxOptimizationSteps); break; case ThumbnailSettings.LayoutModes.ColumnPriority: chartArea.BackColor = System.Drawing.Color.AliceBlue; desired.Text = String.Format ( "{0} Columns; Min {1} Rows; {2} Max Opt Steps", nThumbs, _tnSettings.MinRows, _tnSettings.MaxOptimizationSteps); break; } desired.Text += detailsPage ? "\nDetail Page" : "\nOverview Page"; desired.Text += String.Format (" {0}x{1} ({2:F2}:1)", _tnSettings.Width, _tnSettings.Height, _tnSettings.AspectRatio); desired.Alignment = System.Drawing.ContentAlignment.BottomLeft; desired.X = 1; desired.Y = 95; chart.Annotations.Add (desired); Charting.TextAnnotation layout = new Charting.TextAnnotation (); layout.Font = subTitleFont; layout.Text = String.Format("{0} Layout Mode", _tnSettings.LayoutMode); if (_tnSettings.LayoutMode != ThumbnailSettings.LayoutModes.Actual) layout.Text += String.Format ("\nRow/Column Optimization {0}", _tnSettings.RCOptimization ? "enabled" : "disabled"); layout.Alignment = System.Drawing.ContentAlignment.BottomRight; layout.X = 77; layout.Y = 95; chart.Annotations.Add (layout); chart.Width = 1280; chart.Height = 1024; int lineWidth = 5; int dotsWidth = 2; chartArea.AxisX.Title = "Video Aspect Ratio"; chartArea.AxisX.TitleFont = axisLabelFont; chartArea.AxisX.MajorGrid.Enabled = false; chartArea.AxisX.MajorTickMark.Interval = 0.10; chartArea.AxisX.Minimum = 1.0; chartArea.AxisX.Maximum = 3.0; chartArea.AxisX.Interval = 0.5; chartArea.AxisX.LineWidth = 3; chartArea.AxisX.MajorTickMark.LineWidth = 3; chartArea.AxisX.LabelStyle = labelStyle1; chartArea.AxisX.LabelStyle.Format = "F2"; chartArea.AxisX.IsMarginVisible = true; if (_tnSettings.LayoutMode == ThumbnailSettings.LayoutModes.Auto && crossoverThreshold > 1.0) { Charting.StripLine stripLine = new Charting.StripLine (); stripLine.IntervalOffset = 0.0; stripLine.StripWidth = crossoverThreshold - 1.0; stripLine.Interval = 10000; stripLine.BackColor = System.Drawing.Color.AliceBlue; chartArea.AxisX.StripLines.Add (stripLine); } chartArea.AxisY.Title = "# of Columns or Rows"; chartArea.AxisY.TitleFont = axisLabelFont; chartArea.AxisY.MajorGrid.Enabled = false; chartArea.AxisY.MajorTickMark.Interval = 1.0; chartArea.AxisY.LineWidth = 3; chartArea.AxisY.MajorTickMark.LineWidth = 3; chartArea.AxisY.LabelStyle = labelStyle2; //chartArea.AxisY.LabelStyle.IsEndLabelVisible = false; chartArea.AxisY.IsMarginVisible = true; if (!plotThresholds) { chartArea.AxisY2.Enabled = Charting.AxisEnabled.True; //chartArea.AxisY2.Title = "# of Columns or Rows"; chartArea.AxisY2.TitleFont = axisLabelFont; chartArea.AxisY2.MajorGrid.Enabled = false; chartArea.AxisY2.MajorTickMark.Interval = 1.0; chartArea.AxisY2.LineWidth = 3; chartArea.AxisY2.MajorTickMark.LineWidth = 3; chartArea.AxisY2.LabelStyle = labelStyle3; //chartArea.AxisY2.LabelStyle.IsEndLabelVisible = false; chartArea.AxisY2.IsMarginVisible = true; } Charting.Series seriesNCols = chart.Series.Add ("# of Columns"); seriesNCols.ChartType = Charting.SeriesChartType.StepLine; seriesNCols.ChartArea = "Wasted"; seriesNCols.Legend = "Wasted"; seriesNCols.IsVisibleInLegend = true; seriesNCols.BorderWidth = lineWidth; Charting.Series seriesNRows = chart.Series.Add ("# of Rows"); seriesNRows.ChartType = Charting.SeriesChartType.StepLine; seriesNRows.ChartArea = "Wasted"; seriesNRows.Legend = "Wasted"; seriesNRows.IsVisibleInLegend = true; seriesNRows.BorderWidth = lineWidth; Charting.Series seriesWW = null; Charting.Series seriesWH = null; if (plotThresholds) { chartArea.AxisY2.Title = "% Wasted Thumbnail Width or Height"; chartArea.AxisY2.TitleFont = axisLabelFont; chartArea.AxisY2.MajorGrid.Enabled = false; chartArea.AxisY2.LineWidth = 3; chartArea.AxisY2.MajorTickMark.LineWidth = 3; chartArea.AxisY2.LabelStyle = labelStyle3; //chartArea.AxisY2.LabelStyle.IsEndLabelVisible = false; chartArea.AxisY2.Maximum = 100.0; seriesWW = chart.Series.Add ("%Wasted Width"); seriesWW.ChartType = Charting.SeriesChartType.Line; seriesWW.ChartArea = "Wasted"; seriesWW.Legend = "Wasted"; seriesWW.IsVisibleInLegend = true; seriesWW.BorderWidth = dotsWidth; seriesWW.BorderDashStyle = Charting.ChartDashStyle.Dot; seriesWW.YAxisType = Charting.AxisType.Secondary; seriesWH = chart.Series.Add ("%Wasted Height"); seriesWH.ChartType = Charting.SeriesChartType.Line; seriesWH.ChartArea = "Wasted"; seriesWH.Legend = "Wasted"; seriesWH.IsVisibleInLegend = true; seriesWH.BorderWidth = dotsWidth; seriesWH.BorderDashStyle = Charting.ChartDashStyle.Dot; seriesWH.YAxisType = Charting.AxisType.Secondary; } ThumbnailCreator creator = new ThumbnailCreator (_tnSettings, null); ThumbnailPageLayout container = new ThumbnailPageLayout (_tnSettings); ThumbnailPageLayout newContainer; double wastedWidth, wastedHeight; int extraWidth, extraHeight; double extraWidthPercent, extraHeightPercent; for (double aspectRatio=1.0; aspectRatio <= 3.0; aspectRatio += 0.01) { _tnSettings.ThumbAspectRatio = aspectRatio; ThumbnailGrid tg = creator.CreateThumbnailGrid(_tnSettings.LayoutMode, nThumbs, nCols, nRows, crossoverThreshold); newContainer = tg.Layout; container.CalcWasted (_tnSettings, tg, out wastedWidth, out wastedHeight); extraWidth = (int) (wastedWidth * tg.ThumbWidth); extraHeight = (int) (wastedHeight * tg.ThumbHeight); extraWidthPercent = 100.0 * extraWidth / newContainer.Width; extraHeightPercent = 100.0 * extraHeight / newContainer.Height; THelper.Information (String.Format ( "{9,4}x{10,4} ({13,4:F2}) {0,4:F2} {1,2}x{2,2} {3,3:D}x{4,3:D} " + "{5,6:F2}x{6,6:F2} {7,3:D}x{8,3:D} {11:F1}x{12:F1}", aspectRatio, tg.NColumns, tg.NRows, tg.ThumbWidth, tg.ThumbHeight, wastedWidth, wastedHeight, extraWidth, extraHeight, newContainer.Width, newContainer.Height, extraWidthPercent, extraHeightPercent, newContainer.AspectRatio )); int index; if (plotThresholds) { index = seriesWW.Points.AddXY (aspectRatio, wastedWidth * 100.0); if (wastedWidth == 0.0) seriesWW.Points[index].IsEmpty = true; index = seriesWH.Points.AddXY (aspectRatio, wastedHeight * 100.0); if (wastedHeight == 0.0) seriesWH.Points[index].IsEmpty = true; } seriesNCols.Points.AddXY (aspectRatio, tg.NColumns); seriesNRows.Points.AddXY (aspectRatio, tg.NRows); } chartArea.RecalculateAxesScale (); AddARAnnotation (chart, "Fullscreen 4:3\n(1.33)", 1.33, annotationFont, plotThresholds); AddARAnnotation (chart, "HD 16:9\n(1.78)", 1.78, annotationFont, plotThresholds); AddARAnnotation (chart, "Widescreen\n(1.85)", 1.85, annotationFont, plotThresholds); AddARAnnotation (chart, "CinemaScope\n(2.35)", 2.35, annotationFont, plotThresholds); AddARAnnotation (chart, "Ultra-Panavision\n(2.76)", 2.76, annotationFont, plotThresholds); AddARAnnotation (chart, String.Format ("Layout Threshold\n({0:F2})", crossoverThreshold), crossoverThreshold, _tnSettings.LayoutMode == ThumbnailSettings.LayoutModes.Auto ? annotationFont : annotationItFont, plotThresholds, true); if (_tnSettings.RCOptimization && plotThresholds) { switch (_tnSettings.LayoutMode) { case ThumbnailSettings.LayoutModes.Auto: if (_tnSettings.WidthThreshold == _tnSettings.HeightThreshold) AddThresholdAnnotation (chart, String.Format ("Width & Height Threshold\n" + "({0:F2})", _tnSettings.WidthThreshold), _tnSettings.WidthThreshold, annotationFont); else { AddThresholdAnnotation (chart, String.Format ("Width Threshold\n" + "({0:F2})", _tnSettings.WidthThreshold), _tnSettings.WidthThreshold, annotationFont); AddThresholdAnnotation (chart, String.Format ("Height Threshold\n" + "({0:F2})", _tnSettings.HeightThreshold), _tnSettings.HeightThreshold, annotationFont); } break; case ThumbnailSettings.LayoutModes.RowPriority: AddThresholdAnnotation (chart, String.Format ("Width Threshold\n" + "({0:F2})", _tnSettings.WidthThreshold), _tnSettings.WidthThreshold, annotationFont); break; case ThumbnailSettings.LayoutModes.ColumnPriority: AddThresholdAnnotation (chart, String.Format ("Height Threshold\n" + "({0:F2})", _tnSettings.HeightThreshold), _tnSettings.HeightThreshold, annotationFont); break; } } chart.SaveImage (filename, Charting.ChartImageFormat.Png); THelper.Information ("'{0}' created.", filename); labelStyle1.Dispose (); labelStyle2.Dispose (); labelStyle3.Dispose (); titleFont.Dispose (); subTitleFont.Dispose (); axisFont.Dispose (); annotationFont.Dispose (); annotationItFont.Dispose (); chart.Dispose (); }
/// <summary> /// Create ThumbnailGrid the using desired # of columns and <see cref="ThumbnailSettings"/>. /// </summary> /// <param name="layout">The <see cref="ThumbnailPageLayout"/>.</param> /// <param name="tnSettings">The <see cref="ThumbnailSettings"/>.</param> /// <param name="nColumns">The desired number of columns.</param> /// <param name="aspectRatio">The thumbnail aspect ratio.</param> /// <returns> /// new <see cref="ThumbnailGrid"/> /// </returns> public static ThumbnailGrid CreateUsingNColumnsWastedHeight( ThumbnailPageLayout layout, ThumbnailSettings tnSettings, int nColumns, double aspectRatio ) { ThumbnailPageLayout originalLayout = new ThumbnailPageLayout (layout); ThumbnailGrid thumbnailGrid; #if false SortedList<double,int> wastedHeights = new SortedList<double, int> (); if (debug || !(tnSettings.SkipOptimization || tnSettings.Raw)) { for (int i=nColumns - 1; ; i++) { thumbnailGrid = CreateUsingNColumns (layout, i, aspectRatio); if (thumbnailGrid.NRows <= tnSettings.MaxMultiRows) wastedHeights.Add (thumbnailGrid.WastedHeight, i); if (i > nColumns && thumbnailGrid.WastedHeight <= tnSettings.HeightThreshold) break; } } if (debug) { THelper.Debug (" {0:F2} aspect ratio, {1} header height", aspectRatio, layout.HeaderHeight); foreach (KeyValuePair<double,int> kvp in wastedHeights) { thumbnailGrid = CreateUsingNColumns (layout, kvp.Value, aspectRatio); THelper.Debug(" {0}x{1} {2:F2}", thumbnailGrid.NColumns, thumbnailGrid.NRows, kvp.Key); } } #endif double wastedWidth, wastedHeight; ThumbnailPageLayout newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = CreateUsingNColumns (newLayout, nColumns, aspectRatio); newLayout.AdjustSize (thumbnailGrid); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); if (!tnSettings.RCOptimization) { THelper.Debug (" Row optimization disabled, using {0} rows", thumbnailGrid.NRows); THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" {0}x{1} {2:F3}x{3:F3}", thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); return thumbnailGrid; } bool minSet = false; if (thumbnailGrid.NRows < tnSettings.MinRows) { THelper.Debug (" {0} rows < minimum, setting to {1}", thumbnailGrid.NRows, tnSettings.MinRows); newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = ThumbnailGrid.CreateUsingRaw (newLayout, nColumns, tnSettings.MinRows, aspectRatio, true); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); minSet = true; } if (wastedHeight - tnSettings.HeightThreshold < 0.0025) { THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" {0} rows is good enough, wasted height {1:F3} <= {2:F3}", thumbnailGrid.NRows, wastedHeight, tnSettings.HeightThreshold); THelper.Debug (" {0}x{1} {2:F3}x{3:F3}", thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); if (!minSet) return thumbnailGrid; } int nSteps = 1; while (true) { if (tnSettings.MaxOptimizationSteps > 0 && nSteps > tnSettings.MaxOptimizationSteps) { THelper.Debug (" {0} Max Optimization steps reached.", tnSettings.MaxOptimizationSteps); break; } if (wastedHeight - tnSettings.HeightThreshold >= 0.0025) { double savedWastedHeight = wastedHeight; newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = ThumbnailGrid.CreateUsingRaw (newLayout, nColumns, thumbnailGrid.NRows + 1, aspectRatio, true); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" Wasted height {0:F3} > {1:F3}, increased rows: " + "{2}x{3} {4:F3}x{5:F3} ", savedWastedHeight, tnSettings.HeightThreshold, thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); } // still need to check this if minimum was set. if (wastedWidth - tnSettings.WidthThreshold < 0.005) break; else { double savedWastedWidth = wastedWidth; newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = ThumbnailGrid.CreateUsingRaw (newLayout, nColumns + 1, thumbnailGrid.NRows, aspectRatio, true); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); THelper.Debug (" Now wasted width {0:F3} > {1:F3}, increased columns: " + "{2}x{3} {4:F3}x{5:F3} ", savedWastedWidth, tnSettings.WidthThreshold, thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); } nSteps++; } return thumbnailGrid; #if false if (wastedHeights.Values[0] != nColumns && Math.Abs (desiredWastedHeight - wastedHeights.Keys[0]) < 0.15) { if (debug) THelper.Debug (" {0} columns is close to best.", nColumns); thumbnailGrid = CreateUsingNColumns (layout, nColumns, aspectRatio); } else { if (debug) THelper.Debug (" {0} columns is best.", wastedHeights.Values[0]); thumbnailGrid = CreateUsingNColumns (layout, wastedHeights.Values[0], aspectRatio); } return thumbnailGrid; #endif }
/// <summary> /// Create ThumbnailGrid the using desired # of rows and /// <see cref="ThumbnailSettings"/> - WastedWidth method /// </summary> /// <param name="layout">The <see cref="ThumbnailPageLayout"/>.</param> /// <param name="tnSettings">The <see cref="ThumbnailSettings"/>.</param> /// <param name="nRows">The desired # of rows.</param> /// <param name="aspectRatio">The thumbnail aspect ratio.</param> /// <returns>new <see cref="ThumbnailGrid"/></returns> public static ThumbnailGrid CreateUsingNRowsWastedWidth( ThumbnailPageLayout layout, ThumbnailSettings tnSettings, int nRows, double aspectRatio) { ThumbnailPageLayout originalLayout = new ThumbnailPageLayout (layout); ThumbnailGrid thumbnailGrid; #if false double smallerPenalty = 0.20; double largerPenalty = smallerPenalty / 4.0; SortedList<double, Tuple<double,double,int>> wastedWidths = new SortedList<double, Tuple<double, double, int>> (); Tuple<double, double, int> wastedPenalty; if (debug || !(tnSettings.SkipOptimization || tnSettings.Raw)) { for (int i=tnSettings.MinOverviewRows; ; i++) { thumbnailGrid = CreateUsingNRows (layout, i, aspectRatio); if (i < nRows) wastedPenalty = new Tuple<double, double, int> (thumbnailGrid.WastedWidth, (nRows - i) * smallerPenalty, i); else if (i > nRows) wastedPenalty = new Tuple<double, double, int> (thumbnailGrid.WastedWidth, (i - nRows) * largerPenalty, i); else wastedPenalty = new Tuple<double, double, int> (thumbnailGrid.WastedWidth, 0.0, i); if (thumbnailGrid.NColumns > 2) wastedWidths.Add (wastedPenalty.Item1 + wastedPenalty.Item2, wastedPenalty); if (i > nRows && thumbnailGrid.WastedWidth <= tnSettings.WidthThreshold) break; } } if (debug) { THelper.Debug (" {0:F2} aspect ratio, {1} header height", aspectRatio, layout.HeaderHeight); foreach (KeyValuePair<double,Tuple<double,double,int>> kvp in wastedWidths) { thumbnailGrid = CreateUsingNRows (layout, kvp.Value.Item3, aspectRatio); THelper.Debug (" {0}x{1} {2:F2}={3:F2}+{4:F2}", thumbnailGrid.NColumns, thumbnailGrid.NRows, kvp.Key, kvp.Value.Item1, kvp.Value.Item2); } } #endif double wastedWidth, wastedHeight; ThumbnailPageLayout newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = CreateUsingNRows (newLayout, nRows, aspectRatio); newLayout.AdjustSize (thumbnailGrid); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); if (!tnSettings.RCOptimization) { THelper.Debug (" Column optimization disabled, using {0} columns", thumbnailGrid.NColumns); THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" {0}x{1} {2:F3}x{3:F3}", thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); return thumbnailGrid; } bool minSet = false; if (thumbnailGrid.NColumns < tnSettings.MinColumns) { THelper.Debug (" {0} columns < minimum, setting to {1}", thumbnailGrid.NColumns, tnSettings.MinColumns); newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = ThumbnailGrid.CreateUsingRaw (newLayout, tnSettings.MinColumns, nRows, aspectRatio, false); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); minSet = true; } if (wastedWidth - tnSettings.WidthThreshold < 0.005) { THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" {0} columns is good enough, wasted width {1:F3} <= {2:F3}", thumbnailGrid.NColumns, wastedWidth, tnSettings.WidthThreshold); THelper.Debug (" {0}x{1} {2:F3}x{3:F3}", thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); if (!minSet) return thumbnailGrid; } int nSteps = 1; while (true) { if (tnSettings.MaxOptimizationSteps > 0 && nSteps > tnSettings.MaxOptimizationSteps) { THelper.Debug (" {0} max optimization steps reached.", tnSettings.MaxOptimizationSteps); break; } if (wastedWidth - tnSettings.WidthThreshold >= 0.005) { double savedWastedWidth = wastedWidth; newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = ThumbnailGrid.CreateUsingRaw (newLayout, thumbnailGrid.NColumns + 1, nRows, aspectRatio, false); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" Wasted width {0:F3} > {1:F3}, increased columns: " + "{2}x{3} {4:F3}x{5:F3} ", savedWastedWidth, tnSettings.WidthThreshold, thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); } // still need to check this if minimum was set. if (wastedHeight - tnSettings.HeightThreshold < 0.0025) break; else { double savedWastedHeight = wastedHeight; newLayout = new ThumbnailPageLayout (originalLayout); thumbnailGrid = ThumbnailGrid.CreateUsingRaw (newLayout, thumbnailGrid.NColumns, thumbnailGrid.NRows+1, aspectRatio, false); originalLayout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); THelper.Debug (" Now wasted height {0:F3} > {1:F3}, increased rows: " + "{2}x{3} {4:F3}x{5:F3} ", savedWastedHeight, tnSettings.HeightThreshold, thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); } nSteps++; } return thumbnailGrid; #if false //Following should now be never reached. if (wastedWidths.Values[0].Item1 > 0.60) { thumbnailGrid = ThumbnailGrid.CreateUsingRaw (layout, thumbnailGrid.NColumns + 1, nRows, aspectRatio, false); if (debug) THelper.Debug (" {0}x{1} Best still wastes > 0.60, increasing columns.", thumbnailGrid.NColumns, nRows); return thumbnailGrid; } if (wastedWidths.Values[0].Item3 != nRows && Math.Abs (desiredWastedWidth - wastedWidths.Values[0].Item1) < 0.15) { if (debug) THelper.Debug (" {0} rows is close to best.", nRows); thumbnailGrid = CreateUsingNRows (layout, nRows, aspectRatio); } else { if (debug) THelper.Debug (" {0} rows is best.", wastedWidths.Values[0].Item3); thumbnailGrid = CreateUsingNRows (layout, wastedWidths.Values[0].Item3, aspectRatio); } return thumbnailGrid; #endif }
/// <summary> /// Creates the using actual rows and columns specified. /// </summary> /// <param name="layout">The <see cref="ThumbnailPageLayout"/>.</param> /// <param name="tnSettings">The <see cref="ThumbnailSettings"/>.</param> /// <param name="nColumns">The desired number of columns.</param> /// <param name="nRows">The desired number of rows.</param> /// <param name="aspectRatio">The thumbnail aspect ratio.</param> /// <returns> /// new <see cref="ThumbnailGrid"/> /// </returns> public static ThumbnailGrid CreateUsingActual(ThumbnailPageLayout layout, ThumbnailSettings tnSettings, int nColumns, int nRows, double aspectRatio) { double wastedWidth, wastedHeight; bool fitWidth = tnSettings.ThumbAspectRatio > tnSettings.AspectRatio; ThumbnailGrid thumbnailGrid = CreateUsingRaw (layout, nColumns, nRows, aspectRatio, fitWidth); layout.CalcWasted (tnSettings, thumbnailGrid, out wastedWidth, out wastedHeight); THelper.Debug (" Actual specified, using {0}x{1} ({2})", nColumns, nRows, fitWidth ? "FitWidth" : "FitHeight"); THelper.Debug (" {0:F2} aspect ratio", aspectRatio); THelper.Debug (" {0}x{1} {2:F3}x{3:F3}", thumbnailGrid.NColumns, thumbnailGrid.NRows, wastedWidth, wastedHeight); return thumbnailGrid; }