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"); }
IPixelCanvas RandomSquares__RAW(int count, int square_size, int canvas_size) { var rd = new Random(); var pc = new PixelArrayCanvas(canvas_size, canvas_size); var color = pc.GetColor(System.Windows.Media.Colors.Red); Parallel.For(0, count, i => { var x = rd.Next(0, canvas_size - square_size); var y = rd.Next(0, canvas_size - square_size); pc.DrawRectangle( //pc.Bounds, x, y, square_size, square_size, color); }); return pc; }