Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aero: How to draw solid (opaque) colors on glass?

Using GDI+ to draw various colors:

brush = new SolidBrush(color); graphics.FillRectangle(brush, x, y, width, height); 

You'll notice that no opaque color shows properly on glass: alt text

How do i draw solid colors on glass?


You'll also notice that a fully opaque color is handled differently depending on what color it is:

  • opaque black: fully transparent
  • opaque color: partially transparent
  • opaque white: fully opaque

alt text

Can anyone point me to the documentation on the desktop compositor that explains how different colors are handled?


Update 3

You'll also notice that FillRectangle behaves differently than FillEllipse:

  • FillEllipse with an opaque color draws an opaque color
  • FillRectangle with an opaque color draws partially (or fully) transparent

alt text

Explanation for non-sensical behavior please.

Update 4

Alwayslearning suggested i change the compositing mode. From MSDN:

CompositingMode Enumeration

The CompositingMode enumeration specifies how rendered colors are combined with background colors. This enumeration is used by the Graphics::GetCompositingMode and 'Graphics::SetCompositingMode' methods of the Graphics class.

CompositingModeSourceOver 

Specifies that when a color is rendered, it is blended with the background color. The blend is determined by the alpha component of the color being rendered.

CompositingModeSourceCopy 

Specifies that when a color is rendered, it overwrites the background color. This mode cannot be used along with TextRenderingHintClearTypeGridFit.

From the description of CompositingModeSourceCopy, it sounds like it's not the option i want. From the limitations it imposes, it sounds like the option i want. And with composition, or transparency disabled it isn't the option i want, since it performs a SourceCopy, rather than SourceBlend:

alt text

Fortunately it's not an evil i have to contemplate because it doesn't solve my actual issue. After constructing my graphics object, i tried changed the compositing mode:

graphics = new Graphics(hDC); graphics.SetCompositingMode(CompositingModeSourceCopy); //CompositingModeSourceCopy = 1 

The result has no effect on the output:

alt text

Notes

  • Win32 native
  • not .NET (i.e. native)
  • not Winforms (i.e. native)
  • GDI+ (i.e. native)

See also

  • Aero: How to draw ClearType text on glass?
  • Windows Aero: What color to paint to make “glass” appear?
  • Vista/7: How to get glass color?
like image 946
Ian Boyd Avatar asked Nov 23 '10 16:11

Ian Boyd


1 Answers

Seems to work OK for me. With the lack of a full code example I'm assuming you've got your compositing mode wrong.

public void RenderGdiPlus() {     List<string> colors = new List<string>(new string[] { "000000", "ff0000", "00ff00", "0000ff", "ffffff" });     List<string> alphas = new List<string>(new string[] { "00", "01", "40", "80", "c0", "fe", "ff" });     Bitmap bmp = new Bitmap(200, 300, System.Drawing.Imaging.PixelFormat.Format32bppArgb);      Graphics graphics = Graphics.FromImage(bmp);     graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;     graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;     graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;      graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;     graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;     SolidBrush backBrush = new SolidBrush(Color.FromArgb(254, 131, 208, 129));     graphics.FillRectangle(backBrush, 0, 0, 300, 300);      graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;     Pen pen = new Pen(Color.Gray);     for (int row = 0; row < alphas.Count; row++)     {         string alpha = alphas[row];         for (int column=0; column<colors.Count; column++)         {             string color = "#" + alpha + colors[column];             SolidBrush brush = new SolidBrush(ColorTranslator.FromHtml(color));             graphics.DrawRectangle(pen, 40*column, 40*row, 32, 32);             graphics.FillRectangle(brush, 1+40*column, 1+40*row, 31, 31);         }     }      Graphics gr2 = Graphics.FromHwnd(this.Handle);     gr2.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;     gr2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;     gr2.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;     gr2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;     gr2.DrawImage(bmp, 0, 0); } 
like image 72
AlwaysLearning Avatar answered Sep 29 '22 00:09

AlwaysLearning