none
Picturebox 重叠显示图片时,如何将背景设置为透明? RRS feed

  • 问题

  • 我有一个界面通过图片显示一些状态,实用PictureBox控件叠加。其中,

    - 下面点PictureBox.Image显示背景,背景是回变化的。

    - 上面的PictureBox.Image显示状态,状态点PictureBox只有显示和不现实,该图边缘有空白处,需要透明的效果。

    下层图片我选用的是jpg,上层是png(该图中点背景部分已经通过Photoshop清除并确认确实透明)。

    但测试发现图片透明部分还是白色,见下图:

    十字部分是上层PictureBox,已设置Back.Color 为 Transparent。但没有效果。

    请问如何设置?

    2014年5月22日 1:17

答案

  • 你好:

    Windows Forms应用程序是不支持控件的真正的背景透明的,只能通过一些特殊的方式来达到透明的效果。

    请参考这篇英文文章:

    How to Use Transparent Images and Labels in Windows Forms

    这篇文章中使用的不是PictureBox控件,而是自定义了一个Panel控件,然后在Panel中画上具有透明效果的png图片,步骤很简单:

    1. 创建一个抽象类,继承于Panel类,重写里面的CreateParams属性,OnpaintBackground/Onpaint方法

    abstract public class DrawingArea : Panel
        {
            /// <span class="code-SummaryComment"><summary></span>
            /// Drawing surface where graphics should be drawn.
            /// Use this member in the OnDraw method.
            /// <span class="code-SummaryComment"></summary></span>
            protected Graphics graphics;
    
            /// <span class="code-SummaryComment"><summary></span>
            /// Override this method in subclasses for drawing purposes.
            /// <span class="code-SummaryComment"></summary></span>
            abstract protected void OnDraw();
    
            protected override CreateParams CreateParams
            {
                get
                {
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
    
                    return cp;
                }
            }
    
            protected override void OnPaintBackground(PaintEventArgs pevent)
            {
                // Don't paint background
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                // Update the private member so we can use it in the OnDraw method
                this.graphics = e.Graphics;
    
                // Set the best settings possible (quality-wise)
                this.graphics.TextRenderingHint =
                    System.Drawing.Text.TextRenderingHint.AntiAlias;
                this.graphics.InterpolationMode =
                    System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
                this.graphics.PixelOffsetMode =
                    System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                this.graphics.SmoothingMode =
                    System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    
                // Calls the OnDraw subclass method
                OnDraw();
            } 
        }

    2. 写一个类继承于刚才的这个抽象类,在OnDraw事件中将需要透明处理的png图片画上去

    class BroculosDrawing : DrawingArea
        {
            protected override void OnDraw()
            {
                // Gets the image from the global resources
                Image broculoImage = Image.FromFile("D:\\Images\\test.png");
    
                // Sets the images' sizes and positions
                int width = broculoImage.Size.Width;
                int height = broculoImage.Size.Height;
                Rectangle big = new Rectangle(0, 0, width, height);
    
                // Draws the two images
                this.graphics.DrawImage(broculoImage, big);
    
            }
        }

    3. 编译一下在VS的ToolBox中可以发现刚才创建好的这个已经作了透明处理的Panel控件,直接拖到一个Form中去,就会发现背景是透明的。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 Lannykid 2014年5月27日 6:36
    2014年5月23日 6:47
    版主

全部回复

  • 实际上,不是只有两个PictureBox,叠加层次是这样的:

    GroupBox - PictureBox - PictureBox(下层) - PictureBox(上层)

    而PictureBox(上层)的BackColor设置Transparent 后,显示的颜色是GroupBox而非PictureBox(下层)。

    如果是这样的话,如何实现两层图外加上层背景透明的功能呢?

    2014年5月22日 1:38
  • 你好:

    Windows Forms应用程序是不支持控件的真正的背景透明的,只能通过一些特殊的方式来达到透明的效果。

    请参考这篇英文文章:

    How to Use Transparent Images and Labels in Windows Forms

    这篇文章中使用的不是PictureBox控件,而是自定义了一个Panel控件,然后在Panel中画上具有透明效果的png图片,步骤很简单:

    1. 创建一个抽象类,继承于Panel类,重写里面的CreateParams属性,OnpaintBackground/Onpaint方法

    abstract public class DrawingArea : Panel
        {
            /// <span class="code-SummaryComment"><summary></span>
            /// Drawing surface where graphics should be drawn.
            /// Use this member in the OnDraw method.
            /// <span class="code-SummaryComment"></summary></span>
            protected Graphics graphics;
    
            /// <span class="code-SummaryComment"><summary></span>
            /// Override this method in subclasses for drawing purposes.
            /// <span class="code-SummaryComment"></summary></span>
            abstract protected void OnDraw();
    
            protected override CreateParams CreateParams
            {
                get
                {
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
    
                    return cp;
                }
            }
    
            protected override void OnPaintBackground(PaintEventArgs pevent)
            {
                // Don't paint background
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                // Update the private member so we can use it in the OnDraw method
                this.graphics = e.Graphics;
    
                // Set the best settings possible (quality-wise)
                this.graphics.TextRenderingHint =
                    System.Drawing.Text.TextRenderingHint.AntiAlias;
                this.graphics.InterpolationMode =
                    System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
                this.graphics.PixelOffsetMode =
                    System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                this.graphics.SmoothingMode =
                    System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    
                // Calls the OnDraw subclass method
                OnDraw();
            } 
        }

    2. 写一个类继承于刚才的这个抽象类,在OnDraw事件中将需要透明处理的png图片画上去

    class BroculosDrawing : DrawingArea
        {
            protected override void OnDraw()
            {
                // Gets the image from the global resources
                Image broculoImage = Image.FromFile("D:\\Images\\test.png");
    
                // Sets the images' sizes and positions
                int width = broculoImage.Size.Width;
                int height = broculoImage.Size.Height;
                Rectangle big = new Rectangle(0, 0, width, height);
    
                // Draws the two images
                this.graphics.DrawImage(broculoImage, big);
    
            }
        }

    3. 编译一下在VS的ToolBox中可以发现刚才创建好的这个已经作了透明处理的Panel控件,直接拖到一个Form中去,就会发现背景是透明的。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 Lannykid 2014年5月27日 6:36
    2014年5月23日 6:47
    版主
  • Panel是可行的,但是Panel对图片点兼容不佳,要设置Background同时尺寸无法填充,感谢。

    设置Parent属性可以使PictureBox作背景时透明效果依然有效

    以上是另外一个帖子点回复。

    2014年5月27日 6:42