/// <summary> /// Generates the multi-page thumbnails OBSOLETE. /// </summary> /// <param name="mediaItem">The /// <see cref="Microsoft.Expression.Encoder.MediaItem"/> to generate /// thumbnails for.</param> /// <param name="filename">The display name of the file to generate thumbs for.</param> /// <param name="outputDirectory">The output directory.</param> /// <returns>The number of thumbnails created.</returns> public int GenerateMultiThumbs(MSEEncoder.MediaItem mediaItem, string filename, string outputDirectory) { double thumbAspectRatio = TNSettings.ThumbAspectRatio; ThumbnailPageLayout container = new ThumbnailPageLayout (TNSettings); ThumbnailGrid tgrid; if (thumbAspectRatio < 1.44) tgrid = ThumbnailGrid.CreateUsingNColumns (container, TNSettings, thumbAspectRatio, true, _debug); else tgrid = ThumbnailGrid.CreateUsingNRows (container, TNSettings, thumbAspectRatio, true, _debug); container.AdjustSize (tgrid); //ThumbnailGrid tgrid = ThumbnailGrid.CreateUsingNRows (container, _maxMultiRows, _multiColumns, // aspectRatio, _mThreshold); //container.adjustWidth (tgrid.NColumns, tgrid.ThumbWidth); if (outputDirectory == null) outputDirectory = GetDirectoryName (filename); string fixedFilename = System.IO.Path.GetFileNameWithoutExtension (filename); fixedFilename = fixedFilename.Replace ("{", "("); fixedFilename = fixedFilename.Replace ("}", ")"); string outTemplate = fixedFilename + "_page{0:D4}.jpg"; int nThumbsPerPage = tgrid.NColumns * tgrid.NRows; int nThumbs = (int) ((TNSettings.End - TNSettings.Start).TotalSeconds / TNSettings.Interval.TotalSeconds) + 1; // start adjustment to make thumbnails occur at _interval seconds int nExtraStartSeconds = (int) (TNSettings.Start.TotalSeconds % TNSettings.Interval.TotalSeconds); int nStartIntervals = (int) (TNSettings.Start.TotalSeconds / TNSettings.Interval.TotalSeconds); if (nExtraStartSeconds != 0) { nThumbs++; nStartIntervals++; } int nExtraEndSeconds = (int) (TNSettings.End.TotalSeconds % TNSettings.Interval.TotalSeconds); int nEndIntervals = (int) (TNSettings.End.TotalSeconds / TNSettings.Interval.TotalSeconds); TimeSpan adjustedEnd = TNSettings.End; if (nExtraEndSeconds != 0) { nThumbs++; adjustedEnd = TNSettings.End; //adjustedEnd = new TimeSpan (0, 0, nEndIntervals * // (int) tnSettings.Interval.TotalSeconds); } int nPages = (int) ((float) nThumbs / nThumbsPerPage + 0.5); if (nPages * nThumbsPerPage < nThumbs) nPages++; string stats; if (mediaItem.OriginalVideoSize.Width != TNSettings.SrcRect.Width || mediaItem.OriginalVideoSize.Height != TNSettings.SrcRect.Height || Math.Abs ((double) mediaItem.OriginalVideoSize.Width / mediaItem.OriginalVideoSize.Height - TNSettings.ThumbAspectRatio) > 0.01) { stats = String.Format ("{0}x{1} ({2:F2}:1) [{3}x{4} ({5:F2}:1)] {6} {7}", TNSettings.SrcRect.Width, TNSettings.SrcRect.Height, TNSettings.ThumbAspectRatio, mediaItem.OriginalVideoSize.Width, mediaItem.OriginalVideoSize.Height, (double) mediaItem.OriginalVideoSize.Width / mediaItem.OriginalVideoSize.Height, //getAudioStreamStats(mediaItem), GetFileSizeString (mediaItem.MainMediaFile.FileSize), System.IO.File.GetLastWriteTime (filename).ToString ("g") ); } else { stats = String.Format ("{0}x{1} ({2:F2}:1) {3} {4}", mediaItem.OriginalVideoSize.Width, mediaItem.OriginalVideoSize.Height, TNSettings.ThumbAspectRatio, //getAudioStreamStats(mediaItem), GetFileSizeString (mediaItem.MainMediaFile.FileSize), System.IO.File.GetLastWriteTime (filename).ToString ("g") ); } THelper.Information ("Duration {0} - Generating {1} thumbs every {2} seconds on {3} pages.", mediaItem.FileDuration.ToString (@"h\:mm\:ss"), nThumbs, TNSettings.Interval.TotalSeconds, nPages); ThumbnailMultiWriter mwriter = new ThumbnailMultiWriter (this, tgrid, outputDirectory, filename, outTemplate, TNSettings.Interval, stats, mediaItem.FileDuration, nPages, TNSettings.ScaleFactor, _debug); TimeSpan currentTime = TNSettings.Start; int thumbCount = 0; if (nExtraStartSeconds != 0) { using (System.Drawing.Bitmap resized = GenerateThumbnail (mediaItem, currentTime, tgrid.ThumbWidth, tgrid.ThumbHeight, TNSettings.SrcRect)) { mwriter.Add (resized, currentTime, 0, TimeSpan.Zero); thumbCount++; } currentTime = new TimeSpan (0, 0, 0, 0, (int) (nStartIntervals * TNSettings.Interval.TotalMilliseconds)); } while (currentTime <= adjustedEnd) { using (System.Drawing.Bitmap resized = GenerateThumbnail (mediaItem, currentTime, tgrid.ThumbWidth, tgrid.ThumbHeight, TNSettings.SrcRect)) { mwriter.Add (resized, currentTime, 0, TimeSpan.Zero); thumbCount++; } currentTime += TNSettings.Interval; } if (nExtraEndSeconds != 0 && thumbCount < nThumbs) { using (System.Drawing.Bitmap resized = GenerateThumbnail (mediaItem, TNSettings.End, tgrid.ThumbWidth, tgrid.ThumbHeight, TNSettings.SrcRect)) { mwriter.Add (resized, TNSettings.End, 0, TimeSpan.Zero); thumbCount++; } } mwriter.Close (); return thumbCount; }
/// <summary> /// Creates the thumbnail grid. /// </summary> /// <param name="layoutMode">The <see cref="ThumbnailSettings.LayoutModes"/>.</param> /// <param name="nThumbs">The desired number of rows or columns.</param> /// <param name="nColumns">The number of desired columns.</param> /// <param name="nRows">The number of desired rows.</param> /// <param name="priorityThreshold">The threshold that determines when to switch /// between Column and Row Priority in /// <see cref="ThumbnailSettings.LayoutModes.Auto"/>.</param> /// <returns></returns> public ThumbnailGrid CreateThumbnailGrid(ThumbnailSettings.LayoutModes layoutMode, int nThumbs, int nColumns, int nRows, double priorityThreshold) { ThumbnailGrid tgrid = null; ThumbnailPageLayout container = new ThumbnailPageLayout (TNSettings); double thumbAspectRatio = TNSettings.ThumbAspectRatio; switch (layoutMode) { case ThumbnailSettings.LayoutModes.Auto: { if (thumbAspectRatio < priorityThreshold) { THelper.Debug ("Auto Column Priority Layout (aspect ratio {0:F2} < {1}), using {2} columns", thumbAspectRatio, priorityThreshold, nThumbs); tgrid = ThumbnailGrid.CreateUsingNColumnsWastedHeight (container, TNSettings, nThumbs, thumbAspectRatio); } else { THelper.Debug ("Auto Row Priority Layout (aspect ratio {0:F2} >= {1}), using {2} rows", thumbAspectRatio, priorityThreshold, nThumbs); tgrid = ThumbnailGrid.CreateUsingNRowsWastedWidth (container, TNSettings, nThumbs, thumbAspectRatio); } break; } case ThumbnailSettings.LayoutModes.Actual: { if (TNSettings.LayoutMode == ThumbnailSettings.LayoutModes.Actual) THelper.Debug ("Actual Layout: {0}x{1}", nColumns, nRows); tgrid = ThumbnailGrid.CreateUsingActual (container, TNSettings, nColumns, nRows, thumbAspectRatio); break; } case ThumbnailSettings.LayoutModes.RowPriority: { THelper.Debug ("Row Priority Layout, using {0} rows", nThumbs); tgrid = ThumbnailGrid.CreateUsingNRowsWastedWidth (container, TNSettings, nThumbs, thumbAspectRatio); break; } case ThumbnailSettings.LayoutModes.ColumnPriority: { THelper.Debug ("Column Priority Layout, using {0} columns", nThumbs); tgrid = ThumbnailGrid.CreateUsingNColumnsWastedHeight(container, TNSettings, nThumbs, thumbAspectRatio); break; } } container.AdjustSize (tgrid); return tgrid; }
/// <summary> /// Generates the overview thumbnail page OBSOLETE. /// </summary> /// <param name="mediaItem">The /// <see cref="Microsoft.Expression.Encoder.MediaItem"/> to generate /// thumbnails for.</param> /// <param name="filename">The display name of the file to generate thumbs for.</param> /// <param name="outputDirectory">The output directory.</param> /// <returns>The number of thumbnails created.</returns> public int GenerateOverviewThumbs(MSEEncoder.MediaItem mediaItem, string filename, string outputDirectory) { double thumbAspectRatio = TNSettings.ThumbAspectRatio; ThumbnailPageLayout container = new ThumbnailPageLayout (TNSettings); ThumbnailGrid tgrid; if (thumbAspectRatio < 1.36) tgrid = ThumbnailGrid.CreateUsingNColumns (container, TNSettings, thumbAspectRatio, false, _debug); else tgrid = ThumbnailGrid.CreateUsingNRows (container, TNSettings, thumbAspectRatio, false, _debug); container.AdjustSize (tgrid); if (outputDirectory == null) outputDirectory = GetDirectoryName (filename); string outTemplate = System.IO.Path.GetFileNameWithoutExtension (filename) + "_overview.jpg"; #if true string stats; if (mediaItem.OriginalVideoSize.Width != TNSettings.SrcRect.Width || mediaItem.OriginalVideoSize.Height != TNSettings.SrcRect.Height || Math.Abs ((double) mediaItem.OriginalVideoSize.Width / mediaItem.OriginalVideoSize.Height - TNSettings.ThumbAspectRatio) > 0.01) { stats = String.Format ("{0}x{1} ({2:F2}:1) [{3}x{4} ({5:F2}:1)] {6} {7}", TNSettings.SrcRect.Width, TNSettings.SrcRect.Height, TNSettings.ThumbAspectRatio, mediaItem.OriginalVideoSize.Width, mediaItem.OriginalVideoSize.Height, (double) mediaItem.OriginalVideoSize.Width / mediaItem.OriginalVideoSize.Height, //getAudioStreamStats(mediaItem), GetFileSizeString (mediaItem.MainMediaFile.FileSize), System.IO.File.GetLastWriteTime (filename).ToString ("g") ); } else { stats = String.Format ("{0}x{1} ({2:F2}:1) {3} {4}", mediaItem.OriginalVideoSize.Width, mediaItem.OriginalVideoSize.Height, TNSettings.ThumbAspectRatio, //getAudioStreamStats(mediaItem), GetFileSizeString (mediaItem.MainMediaFile.FileSize), System.IO.File.GetLastWriteTime (filename).ToString ("g") ); } #else string stats = String.Format ("{0}x{1} ({2:F2}:1) [{3}x{4} {5}x{6}] {7} {8}", mediaItem.OriginalVideoSize.Width, mediaItem.OriginalVideoSize.Height, (double) mediaItem.OriginalVideoSize.Width / mediaItem.OriginalVideoSize.Height, //getAudioStreamStats(mediaItem), tgrid.ThumbWidth, tgrid.ThumbHeight, tgrid.NColumns, tgrid.NRows, GetFileSizeString (mediaItem.MainMediaFile.FileSize), System.IO.File.GetLastWriteTime (filename).ToString ("g") ); #endif THelper.Information ("Generating {0} overview page thumbs.", tgrid.NThumbs); ThumbnailWriter writer = new ThumbnailWriter (this, tgrid, outputDirectory, filename, outTemplate, stats, mediaItem.FileDuration, TNSettings.ScaleFactor, _debug); double intervalSeconds = ((TNSettings.End.TotalSeconds - TNSettings.Start.TotalSeconds) / (tgrid.NColumns * tgrid.NRows - 1)); int milliseconds = (int) ((intervalSeconds - Math.Truncate (intervalSeconds)) * 1000 + 0.5); TimeSpan interval = new TimeSpan (0, 0, 0, (int) intervalSeconds, milliseconds); int nThumbsAdded = 0; TimeSpan currentTime = TNSettings.Start; while (currentTime <= TNSettings.End) { using (System.Drawing.Bitmap resized = GenerateThumbnail (mediaItem, currentTime, tgrid.ThumbWidth, tgrid.ThumbHeight, TNSettings.SrcRect)) { writer.Add (resized, currentTime); nThumbsAdded++; } currentTime += interval; } // Last thumb should always be end time. if (nThumbsAdded < tgrid.NThumbs) { using (System.Drawing.Bitmap resized = GenerateThumbnail (mediaItem, TNSettings.End, tgrid.ThumbWidth, tgrid.ThumbHeight, TNSettings.SrcRect)) { writer.Add (resized, TNSettings.End); nThumbsAdded++; } } writer.Close (); return tgrid.NThumbs; }
/// <summary> /// Create ThumbnailGrid the using desired columns & rows. /// </summary> /// <param name="layout">The <see cref="ThumbnailPageLayout"/>.</param> /// <param name="nColumns">The # of columns.</param> /// <param name="nRows">The # of rows.</param> /// <param name="aspectRatio">The thumbnail aspect ratio.</param> /// <param name="fitWidth">if set to <c>true</c>use page layout width, /// otherwise use page layout height.</param> /// <returns>new <see cref="ThumbnailGrid"/></returns> public static ThumbnailGrid CreateUsingRaw(ThumbnailPageLayout layout, int nColumns, int nRows, double aspectRatio, bool fitWidth) { int thumbWidth; int thumbHeight; if (fitWidth) { thumbWidth = layout.CalcThumbWidthFromNCols (nColumns); thumbHeight = (int) (thumbWidth / aspectRatio + 0.5); layout.AdjustHeight (nRows, thumbHeight); } else { thumbHeight = layout.CalcThumbHeightFromNRows (nRows); thumbWidth = (int) (thumbHeight * aspectRatio + 0.5); layout.AdjustWidth (nColumns, thumbWidth); } ThumbnailGrid thumbnailGrid = new ThumbnailGrid (layout, nColumns, nRows, thumbWidth, thumbHeight); layout.AdjustSize (thumbnailGrid); return thumbnailGrid; }
/// <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> /// 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 }