public void FastAlphaBlending() { // http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending // using premultiplied values // out_a = a1 + a2 * (1 - a1) // out_rgb = r1 + r2 * (1 - a1) var c = new PixelArrayCanvas(0, 0); var foreground = c.GetColor(System.Windows.Media.Colors.Green.ChangeAlpha(127)); var background = c.GetColor(System.Windows.Media.Colors.White.ChangeAlpha(127)); // get premultiplied components var background_a = background >> 24 & 0xff; var background_r = background >> 16 & 0xff; var background_g = background >> 8 & 0xff; var background_b = background & 0xff; var foreground_a = foreground >> 24 & 0xff; var foreground_r = foreground >> 16 & 0xff; var foreground_g = foreground >> 8 & 0xff; var foreground_b = foreground & 0xff; var out_a = foreground_a + (1 - foreground_a) * background_a; var out_r = foreground_r + (background_r) * (1 - foreground_a);// / out_a; var out_g = foreground_g + (background_g) * (1 - foreground_a);// / out_a; var out_b = foreground_b + (background_b) * (1 - foreground_a);// / out_a; var pc = new PixelArrayCanvas(10, 10); pc.DrawLineDDA(1, 1, 1, 8, foreground); pc.DrawLineDDA(2, 1, 2, 8, background); pc.DrawLineDDA(4, 1, 4, 2, PixelCanvas.GetColor((int)(out_a ),(int)(out_r ), (int)(out_g ),(int)(out_b ))); var pc3 = new PixelArrayCanvas(10,10); pc3.DrawLineDDA(4,3,4,5, foreground); pc.Blit(pc3, BlendMode.Alpha); out_a = foreground_a + (1 - foreground_a) * background_a; out_r = foreground_r + (background_r) * (1 - foreground_a) / out_a; out_g = foreground_g + (background_g) * (1 - foreground_a) / out_a; out_b = foreground_b + (background_b) * (1 - foreground_a) / out_a; pc.DrawLineDDA(4, 6, 4, 8, PixelCanvas.GetColor((int)(out_a ), (int)(out_r ), (int)(out_g ), (int)(out_b ))); pc.Save(@"c:\temp\blend_xxx.bmp"); }
public void Blit() { var rd = new Random(); var rc = new RawDrawCommand((pc, ct) => { pc.DrawRectangle(10, 10, 20, 20, pc.GetColor(Colors.Red)); }); var wpfc = new WpfDrawingContextDrawCommand((pc, cx, ct) => { var c = pc.GetColor(Colors.Turquoise); var pen = new Pen(Brushes.Turquoise, 2.0); pen.Freeze(); for (int i = 0; i < 100; i++) { var p1 = new Point( rd.Next(1000, 1300), rd.Next(1000, 1300)); var p2 = new Point( rd.Next(1000, 1300), rd.Next(1000, 1300)); if (p1.ToPoint2D().Distance(p2.ToPoint2D()).IsLessThan(1)) continue; pc.DrawLineWu((int)p1.X, (int)p1.Y, (int)p2.X, (int)p2.Y, c); //_cx.DrawLine(pen, p1, p2); } }); var wpfc2 = new WpfDrawingContextDrawCommand((pc, cx, ct) => { for (int i = 0; i < 1000; i++) { var pen = new Pen(Brushes.Moccasin, 2.0); pen.Freeze(); cx.DrawLine(pen, new Point( rd.Next(750, 900), rd.Next(750, 900)), new Point( rd.Next(750, 900), rd.Next(750, 900))); } }); var wpfc3 = new WpfDrawingContextDrawCommand((pc, cx, ct) => { for (int i = 0; i < 1000; i++) { var pen = new Pen(Brushes.Moccasin, 2.0); pen.Freeze(); cx.DrawLine(pen, new Point( rd.Next(500, 600), rd.Next(500, 600)), new Point( rd.Next(500, 600), rd.Next(500, 600))); } }); var wpfc4 = new WpfDrawingContextDrawCommand((pc, cx, ct) => { for (int i = 0; i < 1000; i++) { var pen = new Pen(Brushes.Ivory, 2.0); pen.Freeze(); cx.DrawLine(pen, new Point( rd.Next(0, 2000), rd.Next(50, 2500)), new Point( rd.Next(0, 2000), rd.Next(50, 2500))); } }); var wpfc5 = new WpfDrawingContextDrawCommand((pc, cx, ct) => { for (int i = 0; i < 1000; i++) { var pen = new Pen(Brushes.Navy, 2.0); pen.Freeze(); cx.DrawLine(pen, new Point( rd.Next(0, 2000), rd.Next(50, 500)), new Point( rd.Next(0, 2000), rd.Next(50, 500))); } }); var wpfc6 = new WpfDrawingContextDrawCommand((pc, cx, ct) => { for (int i = 0; i < 1000; i++) { var pen = new Pen(Brushes.Crimson, 2.0); pen.Freeze(); cx.DrawLine(pen, new Point( rd.Next(100, 200), rd.Next(100, 200)), new Point( rd.Next(100, 200), rd.Next(100, 200))); } }); var wpfc7 = new WpfDrawingContextDrawCommand((pc, cx, ct) => { for (int i = 0; i < 1000; i++) { var pen = new Pen(Brushes.Coral, 2.0); pen.Freeze(); cx.DrawLine(pen, new Point( rd.Next(0, 50), rd.Next(0, 50)), new Point( rd.Next(0, 50), rd.Next(0, 50))); } }); var sw = Stopwatch.StartNew(); var canvas = new PixelArrayCanvas(2000, 2000); Trace.WriteLine("CREATED " + sw.GetElapsedAndRestart().TotalMilliseconds); //pc.Execute(new CanvasCommand[] { rc, wpfc, wpfc2, wpfc3, wpfc4, wpfc5, wpfc6, wpfc7 }); canvas.Execute(new CanvasCommand[] { rc, wpfc }, CancellationToken.None); Trace.WriteLine("EXECUTE " + sw.GetElapsedAndRestart().TotalMilliseconds); var bmp = canvas.ToWriteableBitmap(); Trace.WriteLine("BMP " + sw.GetElapsedAndRestart().TotalMilliseconds); canvas.Save(@"c:\temp\shit\1.png"); Trace.WriteLine("SAVE " + sw.GetElapsedAndRestart().TotalMilliseconds); //InvocationThrottle t = new InvocationThrottle(); //var total_ms = 0.0; //for (int i = 0; i < 10000; i++) //{ // Thread.Sleep(10); // var g = Guid.NewGuid(); // var sw = Stopwatch.StartNew(); // t.InvokeAsync((ct) => // { // Thread.Sleep(75); // Trace.WriteLine("RUN TO COMPLETION"); // }); // sw.Stop(); // total_ms += sw.Elapsed.TotalMilliseconds; // Trace.WriteLine("WAIT: " + sw.Elapsed.Milliseconds); // Trace.WriteLine("WAIT ALL: " + total_ms); //} //Thread.Sleep(10000); //var sw = Stopwatch.StartNew(); ////for (int i = 0; i < 10000; i++) //{ // var pen = new PixelArrayCanvas(10, 10); // pen.DrawRectangle(0, 0, 3, 3, pen.GetColor(Colors.Red)); // var cv = new PixelArrayCanvas(1000, 1000); // cv.DrawLineWu(100, 100, 900, 900, cv.GetColor(Colors.Red)); // cv.Save(@"c:\temp\shit\1.png"); //} //sw.Stop(); //Trace.WriteLine(sw.Elapsed.TotalMilliseconds); //int count = 100; //var sw = Stopwatch.StartNew(); //Render(count, 100); //Trace.WriteLine("100x100: " + sw.GetElapsedAndRestart().TotalMilliseconds); //Render(count, 1000); //Trace.WriteLine("1kx1k: " + sw.GetElapsedAndRestart().TotalMilliseconds); //Render(count, 2000); //Trace.WriteLine("2kx2k: " + sw.GetElapsedAndRestart().TotalMilliseconds); }