public generateWangTilesThreadParams_t(WangTileSet wangTileSet, int numColors, int samplesPerTile, int numThreads) { this.wangTileSet = wangTileSet; this.numColors = numColors; this.samplesPerTile = samplesPerTile; this.numThreads = numThreads; }
public WTStipple(Image source, WangTileSet tileSet, int tonalRange, Bitmap dest) { // Convert source image to grayscale Bitmap bmp = new Bitmap(source.Width, source.Height); Graphics g = Graphics.FromImage(bmp); g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height)); float[,] grayscale = ToDensity(bmp); this.tileSet = tileSet; // Subdivide image recusively as long as we need more density on each leave's tile // to account for the underlying sampled region on the image ImageTreeNode root = new ImageTreeNode(); Random r = new Random(tileSet.tiles.Count); root.tile = r.Next(tileSet.tiles.Count); Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); int minSize = 8; Graphics g2 = Graphics.FromImage(dest); g2.Clear(Color.White); Refine_r(root, rect, grayscale, minSize, 0, 5, tonalRange, dest); }
public static WangTileSet FromFile(string sourceFile) { WangTileSet wts = new WangTileSet(); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(wts.GetType()); System.IO.StreamReader file = new System.IO.StreamReader(sourceFile); wts = (WangTileSet)serializer.Deserialize(file); wts.SortTiles(); wts.MakeRecursive(); file.Close(); return(wts); }
public WTStipple(Image source, WangTileSet tileSet, int tonalRange, Bitmap dest ) { // Convert source image to grayscale Bitmap bmp = new Bitmap(source.Width, source.Height); Graphics g = Graphics.FromImage(bmp); g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height)); float[,] grayscale = ToDensity(bmp); this.tileSet = tileSet; // Subdivide image recusively as long as we need more density on each leave's tile // to account for the underlying sampled region on the image ImageTreeNode root = new ImageTreeNode(); Random r = new Random(tileSet.tiles.Count); root.tile = r.Next(tileSet.tiles.Count); Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); int minSize = 8; Graphics g2 = Graphics.FromImage(dest); g2.Clear(Color.White); Refine_r(root, rect, grayscale, minSize, 0, 5, tonalRange, dest ); }
private void GenerateStippling(object obj) { generateStipplingParams_t param = (generateStipplingParams_t)obj; if (param.wangTilesPath.Length > 0) { // Stipple using Wang Tiles WangTileSet wts = WangTileSet.FromFile(param.wangTilesPath); int tonalRange = (int)Math.Pow(10, (int)(param.toneScaleBias * 6)) + 10000; // this is merely a heuristic trying to produce sensible values for the tonalRange variable from a [0,1] source range WTStipple stipple = new WTStipple(param.source, wts, tonalRange, param.result); } else { // Stipple using Adaptive Incremental algorithm if (AIS.OnAISDebugStep == null) { AIS.OnAISDebugStep += OnAISDebugStep; } int K = (int)((1.0f - param.toneScaleBias) * 2048 + 64); // this is merely a heuristic trying to produce sensible values for the K variable from a [0,1] source range AIS.Stipple(param.source, K, param.result); } finishedStippling.Set(); }
public static WangTileSet FromFile(string sourceFile) { WangTileSet wts = new WangTileSet(); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(wts.GetType()); System.IO.StreamReader file = new System.IO.StreamReader(sourceFile); wts = (WangTileSet)serializer.Deserialize(file); wts.SortTiles(); wts.MakeRecursive(); file.Close(); return wts; }
private void GenerateWangTiles() { if (generatingTiles) { requestedAbort = true; return; } splitContainer2.Panel1.Enabled = false; generatingTiles = true; requestedAbort = false; wtGenerate.Text = "Cancel"; if (wtDestFilePath.Text.Length == 0) { MessageBox.Show("Please select a valid destination file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } wtProgress.Value = 0; wtConsole.Items.Clear(); debugSteps = new Queue<Image>(); int samplesPerTile = Int32.Parse(wtSamplesPerTile.Text); int numColors = (int)wtEdgeColors.Value; if (WangTileSet.OnProgressReport == null) WangTileSet.OnProgressReport += new BlueNoise.WangTileSet.ProgressReportDelegate(OnWTProgress); if (WangTileSet.OnConsoleMessage == null) WangTileSet.OnConsoleMessage += new BlueNoise.WangTileSet.ConsoleDelegate(OnWTConsoleMessage); int numThreads = 8; // TODO: proper task-based system instead of limiting the worker thread count if (wtDebugSteps.Checked) { // restrict to single-threaded numThreads = 1; wtDebugPlayStop.Enabled = true; // Setup debug callbacks if (WangTile.OnDebugStep == null) WangTile.OnDebugStep += new BlueNoise.WangTile.WangTileDebugStepDelegate(OnWangTileDebugStep); if (WangTileSet.OnDebugStep == null) WangTileSet.OnDebugStep += new WangTileSet.WangTileDebugStepDelegate(OnWangTileDebugStep); } else { WangTile.OnDebugStep -= OnWangTileDebugStep; WangTileSet.OnDebugStep -= OnWangTileDebugStep; } WangTileSet wangTileSet = new WangTileSet(); Thread t = new Thread(GenerateWangTilesThreadStart); progress = new AutoResetEvent(false); WaitHandle[] waitHandles = { progress }; generateWangTilesThreadParams_t threadParams = new generateWangTilesThreadParams_t(wangTileSet, numColors, samplesPerTile, numThreads); t.Start(threadParams); bool aborted = false; do { aborted = this.Visible == false || requestedAbort; if (aborted) { t.Abort(); break; } bool receivedProgress = WaitHandle.WaitAll(waitHandles, 100); if (receivedProgress) { // progress report ProcessConsoleMessages(); Image img = GetDebugImage(); if (img != null) wtDebugImg.Image = img; wtProgress.Value = wtProgress.Minimum + (int)((wtProgress.Maximum - wtProgress.Minimum) * lastProgressReport); if (stopDebug) Monitor.Enter(debugStepLocker); } Application.DoEvents(); // prevent the process from becoming unresponsive for too long and freeze } while (t.ThreadState != System.Threading.ThreadState.Stopped); if (aborted) { wtProgress.Value = 0; wtConsole.Items.Clear(); debugSteps = new Queue<Image>(); if (stopDebug) Monitor.Exit(debugStepLocker); } else { // flush pending console messages and debug images ProcessConsoleMessages(); Image img; do { img = GetDebugImage(); if (img != null) wtDebugImg.Image = img; } while (img != null); // Save results OnWTConsoleMessage("Saving results to " + wtDestFilePath.Text); ProcessConsoleMessages(); wangTileSet.Serialize(wtDestFilePath.Text); OnWTConsoleMessage("Finished!"); ProcessConsoleMessages(); } // restore UI status wtGenerate.Text = "Generate Tiles"; generatingTiles = false; requestedAbort = false; splitContainer2.Panel1.Enabled = true; wtDebugPlayStop.Enabled = false; wtDebugStepOnce.Enabled = false; if (stopDebug) { stopDebug = false; } }
private void GenerateWangTiles() { if (generatingTiles) { requestedAbort = true; return; } splitContainer2.Panel1.Enabled = false; generatingTiles = true; requestedAbort = false; wtGenerate.Text = "Cancel"; if (wtDestFilePath.Text.Length == 0) { MessageBox.Show("Please select a valid destination file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } wtProgress.Value = 0; wtConsole.Items.Clear(); debugSteps = new Queue <Image>(); int samplesPerTile = Int32.Parse(wtSamplesPerTile.Text); int numColors = (int)wtEdgeColors.Value; if (WangTileSet.OnProgressReport == null) { WangTileSet.OnProgressReport += new BlueNoise.WangTileSet.ProgressReportDelegate(OnWTProgress); } if (WangTileSet.OnConsoleMessage == null) { WangTileSet.OnConsoleMessage += new BlueNoise.WangTileSet.ConsoleDelegate(OnWTConsoleMessage); } int numThreads = 8; // TODO: proper task-based system instead of limiting the worker thread count if (wtDebugSteps.Checked) { // restrict to single-threaded numThreads = 1; wtDebugPlayStop.Enabled = true; // Setup debug callbacks if (WangTile.OnDebugStep == null) { WangTile.OnDebugStep += new BlueNoise.WangTile.WangTileDebugStepDelegate(OnWangTileDebugStep); } if (WangTileSet.OnDebugStep == null) { WangTileSet.OnDebugStep += new WangTileSet.WangTileDebugStepDelegate(OnWangTileDebugStep); } } else { WangTile.OnDebugStep -= OnWangTileDebugStep; WangTileSet.OnDebugStep -= OnWangTileDebugStep; } WangTileSet wangTileSet = new WangTileSet(); Thread t = new Thread(GenerateWangTilesThreadStart); progress = new AutoResetEvent(false); WaitHandle[] waitHandles = { progress }; generateWangTilesThreadParams_t threadParams = new generateWangTilesThreadParams_t(wangTileSet, numColors, samplesPerTile, numThreads); t.Start(threadParams); bool aborted = false; do { aborted = this.Visible == false || requestedAbort; if (aborted) { t.Abort(); break; } bool receivedProgress = WaitHandle.WaitAll(waitHandles, 100); if (receivedProgress) { // progress report ProcessConsoleMessages(); Image img = GetDebugImage(); if (img != null) { wtDebugImg.Image = img; } wtProgress.Value = wtProgress.Minimum + (int)((wtProgress.Maximum - wtProgress.Minimum) * lastProgressReport); if (stopDebug) { Monitor.Enter(debugStepLocker); } } Application.DoEvents(); // prevent the process from becoming unresponsive for too long and freeze } while (t.ThreadState != System.Threading.ThreadState.Stopped); if (aborted) { wtProgress.Value = 0; wtConsole.Items.Clear(); debugSteps = new Queue <Image>(); if (stopDebug) { Monitor.Exit(debugStepLocker); } } else { // flush pending console messages and debug images ProcessConsoleMessages(); Image img; do { img = GetDebugImage(); if (img != null) { wtDebugImg.Image = img; } } while (img != null); // Save results OnWTConsoleMessage("Saving results to " + wtDestFilePath.Text); ProcessConsoleMessages(); wangTileSet.Serialize(wtDestFilePath.Text); OnWTConsoleMessage("Finished!"); ProcessConsoleMessages(); } // restore UI status wtGenerate.Text = "Generate Tiles"; generatingTiles = false; requestedAbort = false; splitContainer2.Panel1.Enabled = true; wtDebugPlayStop.Enabled = false; wtDebugStepOnce.Enabled = false; if (stopDebug) { stopDebug = false; } }