private Lazy <BitmapSource> CreateLazyBitmap(StandardRgbBitmap sourceBitmap, StandardRgbColor[] colors, int[] clusterWeights, StandardRgbColor[] clusterColors) { return(new Lazy <BitmapSource>(() => { UpdateColorHistogram(clusterWeights, clusterColors); return new StandardRgbBitmap(colors, sourceBitmap.Width, sourceBitmap.Height, sourceBitmap.DpiX, sourceBitmap.DpiY).ToBitmapSource(); })); }
public static byte[] ToBgra32PixelArray(this StandardRgbBitmap bitmap, out int stride) { stride = bitmap.Width * sizeof(int); byte[] rawPixels = new byte[stride * bitmap.Height]; for (int i = 0; i < rawPixels.Length; i += 4) { int source = i / 4; rawPixels[i] = bitmap.Pixels[source].B; rawPixels[i + 1] = bitmap.Pixels[source].G; rawPixels[i + 2] = bitmap.Pixels[source].R; rawPixels[i + 3] = 0xFF; } return(rawPixels); }
private async Task ComputeSingle() { int clusters; if (!int.TryParse(ClusterCountSingle.Text, out clusters)) { MessageBox.Show("Could not parse the cluster count"); return; } if (clusters < 1 || clusters > 100) { MessageBox.Show("Clusters must be between 1 and 100"); return; } StandardRgbBitmap sourceBitmap = sourceImage.ToStandardRgbBitmap(); Func <Task>[] tasks = { () => rgbOperation.RunAsync(sourceBitmap, clusters, originalFileName, ShowSteps.IsChecked == true), () => cieLuvOperation.RunAsync(sourceBitmap, clusters, originalFileName, ShowSteps.IsChecked == true), () => cieLabOperation.RunAsync(sourceBitmap, clusters, originalFileName, ShowSteps.IsChecked == true) }; if (ParallelExecution.IsChecked == true) { await Task.WhenAll(tasks.Select(t => t())); } else { foreach (var t in tasks) { await t(); } } }
public async Task RunAsync(StandardRgbBitmap sourceBitmap, int clusters, string originalFileName, bool showAllSteps) { this.originalFileName = originalFileName; this.Bitmap = null; IsRunning = true; IsComplete = false; ColorWeights = null; Colors = null; PixelWidth = sourceBitmap.Width; PixelHeight = sourceBitmap.Height; DateTime startTime = DateTime.Now; string currentStatus = "Computing clusters..."; Lazy <BitmapSource> currentBitmap = new Lazy <BitmapSource>(() => null); EventHandler onTick = (sender, e) => { Status = $"{currentStatus} [{DateTime.Now - startTime:mm\\:ss}]"; Bitmap = currentBitmap.Value; }; DispatcherTimer timer = new DispatcherTimer(TimeSpan.FromMilliseconds(100), DispatcherPriority.Normal, onTick, Dispatcher.CurrentDispatcher); timer.Start(); BitmapCluster targetBitmap = null; if (clusters < 16) { currentStatus = "Creating initial 16-cluster seed... (iteration 0)"; targetBitmap = new BitmapCluster(sourceBitmap.Pixels, colorSpace, 16); await targetBitmap.ClusterAsync(async i => { currentStatus = $"Creating initial 16-cluster seed... (iteration {i})"; if (showAllSteps) { var currentBitmapContent = await targetBitmap.RenderAsync(); currentBitmap = CreateLazyBitmap(sourceBitmap, currentBitmapContent, targetBitmap.GetClusterWeights(), targetBitmap.GetClusterMeans()); } }, 3); currentStatus = $"Rendering 16-cluster image..."; var intermediateBitmapContent = await targetBitmap.RenderAsync(); currentBitmap = CreateLazyBitmap(sourceBitmap, intermediateBitmapContent, targetBitmap.GetClusterWeights(), targetBitmap.GetClusterMeans()); currentStatus = $"Choosing refined seed colors..."; var newSeedClusters = await targetBitmap.ChooseDifferentiatedClusters(clusters); targetBitmap = new BitmapCluster(sourceBitmap.Pixels, colorSpace, newSeedClusters); } else { targetBitmap = new BitmapCluster(sourceBitmap.Pixels, colorSpace, clusters); } currentStatus = $"Computing {clusters}-cluster image... (iteration 0)"; await targetBitmap.ClusterAsync(async i => { currentStatus = $"Computing {clusters}-cluster image... (iteration {i})"; if (showAllSteps) { var currentBitmapContent = await targetBitmap.RenderAsync(); currentBitmap = CreateLazyBitmap(sourceBitmap, currentBitmapContent, targetBitmap.GetClusterWeights(), targetBitmap.GetClusterMeans()); } }, 200); currentStatus = $"Rendering {clusters}-cluster image..."; var finalBitmapContent = await targetBitmap.RenderAsync(); currentBitmap = CreateLazyBitmap(sourceBitmap, finalBitmapContent, targetBitmap.GetClusterWeights(), targetBitmap.GetClusterMeans()); Bitmap = currentBitmap.Value; timer.Stop(); Status = null; IsRunning = false; IsComplete = true; }
public static BitmapSource ToBitmapSource(this StandardRgbBitmap bitmap) { byte[] rawPixels = ToBgra32PixelArray(bitmap, out int stride); return(BitmapSource.Create(bitmap.Width, bitmap.Height, bitmap.DpiX, bitmap.DpiY, PixelFormats.Bgra32, null, rawPixels, stride)); }