c#图片框透明背景似乎不起作用。

时间:2021-03-31 03:18:51

For a project of mine I need images to display with a transparent background. I made some .png images that have a transparent background(to check this I opened them in Photoshop). Now I have a class that extends PictureBox:

对于我的一个项目,我需要用透明背景来显示图像。我制作了一些具有透明背景的png图像(我在Photoshop中打开它们)。现在我有一个扩展图片框的类:

class Foo : PictureBox
{
    public Foo(int argument)
        : base()
    {
        Console.WriteLine(argument);//different in the real application of course.
        //MyProject.Properties.Resources.TRANSPARENCYTEST.MakeTransparent(MyProject.Properties.Resources.TRANSPARENCYTEST.GetPixel(1,1)); //<-- also tried this
        this.Image = MyProject.Properties.Resources.TRANSPARENCYTEST;
        ((Bitmap)this.Image).MakeTransparent(((Bitmap)this.Image).GetPixel(1, 1));
        this.SizeMode = PictureBoxSizeMode.StretchImage;
        this.BackColor = System.Drawing.Color.Transparent;
    }
}

this however just displays the picturebox with a white background, I just can't seem to make it work with a transparent background.

然而,这只是显示了一个白色背景的图片框,我只是无法让它在透明背景下工作。

6 个解决方案

#1


20  

It probably works perfectly. You are seeing what's behind the picture box control. Which is the form. Whose BackColor is probably white. You can set the form's BackgroundImage property to be sure, you should see the image through the picture box. Like this:

它可能完全工作。你看到的是图片框控件背后的内容。这是表单。他的背景颜色可能是白色的。您可以设置表单的BackgroundImage属性以确定,您应该通过图片框看到图像。是这样的:

c#图片框透明背景似乎不起作用。

Punching a hole through both the picture box and the form requires a bigger weapon, Form.TransparencyKey

在图片框和窗体上打一个洞,需要一个更大的武器。

#2


37  

If you want to overlay images over images (and not images over form), this would make the trick:

如果你想要在图像上覆盖图像(而不是图像),这将是一个技巧:

overImage.Parent = backImage;
overImage.BackColor = Color.Transparent;
overImage.Location = thePointRelativeToTheBackImage;

Where overImage and backImage are PictureBox with png (with transparent background).

其中,overImage和backImage是带有png(具有透明背景)的图片框。

This is because, as said before, the transparency of an image is rendered using the back color of the Parent container. PictureBoxes haven't a "Parent" property so you have to make it manually (or create a cutom control of course).

这是因为,如前所述,图像的透明性是使用父容器的后颜色来呈现的。图片框没有“父”属性,所以您必须手动创建它(或者创建一个cutom控件)。

#3


12  

There's an excellent solution on the CodeProject website at

CodeProject网站上有一个很好的解决方案。

Making Transparent Controls - No Flickering

做透明的控制——不要闪烁。

essentially the trick is to override the paintbackground event so as to loop through all the controls underlying the picturebox and redraw them. The function is:-

本质上,技巧是覆盖paintbackground事件,以便循环遍历图片框背后的所有控件并重新绘制它们。功能:-

protected override void OnPaintBackground(PaintEventArgs e)
       // Paint background with underlying graphics from other controls
   {
       base.OnPaintBackground(e);
       Graphics g = e.Graphics;

       if (Parent != null)
       {
           // Take each control in turn
           int index = Parent.Controls.GetChildIndex(this);
           for (int i = Parent.Controls.Count - 1; i > index; i--)
           {
               Control c = Parent.Controls[i];

               // Check it's visible and overlaps this control
               if (c.Bounds.IntersectsWith(Bounds) && c.Visible)
               {
                   // Load appearance of underlying control and redraw it on this background
                   Bitmap bmp = new Bitmap(c.Width, c.Height, g);
                   c.DrawToBitmap(bmp, c.ClientRectangle);
                   g.TranslateTransform(c.Left - Left, c.Top - Top);
                   g.DrawImageUnscaled(bmp, Point.Empty);
                   g.TranslateTransform(Left - c.Left, Top - c.Top);
                   bmp.Dispose();
               }
           }
       }
   }

#4


4  

I know your Question is founded in C#, but due to the similarity, & ease of conversion from VB.NET, I'll add a full VB version that also allows updating of the control's background as you move it around.

我知道您的问题是在c#中创建的,但是由于相似,并且容易从VB中转换。NET,我将添加一个完整的VB版本,当你移动它时,它还允许更新控件的背景。

You already have an answer, but this is for others who find this post by search engines, & would like a VB version, or simply want to find a FULL convertible sample if they also need it in C#.

你已经有了答案,但这是给那些通过搜索引擎找到这篇文章的人的,他们想要一个VB版本的,或者想要找到一个完全可转换的样本,如果他们还需要c#的话。

Create a new Custom Control Class, & paste the following into it... overwriting the default class stuff:

创建一个新的自定义控件类,并将以下内容粘贴到它…覆盖默认的类:

Custom Control Class:

自定义控件类:

Public Class TransparentPictureBox
    Private WithEvents refresher As Timer
    Private _image As Image = Nothing

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        refresher = New Timer()
        'refresher.Tick += New EventHandler(AddressOf Me.TimerOnTick)
        refresher.Interval = 50
        refresher.Start()

    End Sub

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H20
            Return cp
        End Get
    End Property

    Protected Overrides Sub OnMove(ByVal e As EventArgs)
        MyBase.OnMove(e)
        MyBase.RecreateHandle()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here
        If _image IsNot Nothing Then
            e.Graphics.DrawImage(_image, CInt(Width / 2) - CInt(_image.Width / 2), CInt(Height / 2) - CInt(_image.Height / 2))
        End If
    End Sub


    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
        ' Paint background with underlying graphics from other controls
        MyBase.OnPaintBackground(e)
        Dim g As Graphics = e.Graphics

        If Parent IsNot Nothing Then
            ' Take each control in turn
            Dim index As Integer = Parent.Controls.GetChildIndex(Me)
            For i As Integer = Parent.Controls.Count - 1 To index + 1 Step -1
                Dim c As Control = Parent.Controls(i)

                ' Check it's visible and overlaps this control
                If c.Bounds.IntersectsWith(Bounds) AndAlso c.Visible Then
                    ' Load appearance of underlying control and redraw it on this background
                    Dim bmp As New Bitmap(c.Width, c.Height, g)
                    c.DrawToBitmap(bmp, c.ClientRectangle)
                    g.TranslateTransform(c.Left - Left, c.Top - Top)
                    g.DrawImageUnscaled(bmp, Point.Empty)
                    g.TranslateTransform(Left - c.Left, Top - c.Top)
                    bmp.Dispose()
                End If
            Next
        End If
    End Sub

    Public Property Image() As Image
        Get
            Return _image
        End Get
        Set(value As Image)
            _image = value
            MyBase.RecreateHandle()
        End Set
    End Property

    Private Sub refresher_Tick(sender As Object, e As System.EventArgs) Handles refresher.Tick
        MyBase.RecreateHandle()
        refresher.Stop()
    End Sub
End Class

...save the class, then clean your project, & build again. The new control should appear as a new tool Item. Find it, & drag it to your form.

…保存类,然后清理您的项目,并重新构建。新的控件应该作为一个新的工具项出现。找到它,并把它拖到你的表单上。

I have had issues with this control though... It happens when I try to load an animated "Loading" .gif image.

我对这个控制有些问题……当我尝试加载一个动画“加载”.gif图像时,它就会发生。

The image does not animate, & also has display problems when you hide the control, then try to display it again.

图像没有动画效果,当您隐藏控件时也会显示问题,然后尝试再次显示它。

Sort those issues out, & you'll have a perfect Custom Control Class. :)

解决这些问题,你将拥有一个完美的自定义控件类。:)

EDIT:

编辑:

I have no idea if the following will work in C#'s IDE or not, but here's my attempt at conversion:

我不知道下面是否会在c#的IDE中工作,但是我尝试转换:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class TransparentPictureBox
{
    private Timer withEventsField_refresher;
    private Timer refresher {
        get { return withEventsField_refresher; }
        set {
            if (withEventsField_refresher != null) {
                withEventsField_refresher.Tick -= refresher_Tick;
            }
            withEventsField_refresher = value;
            if (withEventsField_refresher != null) {
                withEventsField_refresher.Tick += refresher_Tick;
            }
        }
    }

    private Image _image = null;

    public TransparentPictureBox()
    {
        // This call is required by the designer.
        InitializeComponent();

        // Add any initialization after the InitializeComponent() call.
        refresher = new Timer();
        //refresher.Tick += New EventHandler(AddressOf Me.TimerOnTick)
        refresher.Interval = 50;
        refresher.Start();

    }

    protected override CreateParams CreateParams {
        get {
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | 0x20;
            return cp;
        }
    }

    protected override void OnMove(EventArgs e)
    {
        base.OnMove(e);
        base.RecreateHandle();
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        base.OnPaint(e);

        //Add your custom paint code here
        if (_image != null) {
            e.Graphics.DrawImage(_image, Convert.ToInt32(Width / 2) - Convert.ToInt32(_image.Width / 2), Convert.ToInt32(Height / 2) - Convert.ToInt32(_image.Height / 2));
        }
    }


    protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
    {
        // Paint background with underlying graphics from other controls
        base.OnPaintBackground(e);
        Graphics g = e.Graphics;

        if (Parent != null) {
            // Take each control in turn
            int index = Parent.Controls.GetChildIndex(this);
            for (int i = Parent.Controls.Count - 1; i >= index + 1; i += -1) {
                Control c = Parent.Controls(i);

                // Check it's visible and overlaps this control
                if (c.Bounds.IntersectsWith(Bounds) && c.Visible) {
                    // Load appearance of underlying control and redraw it on this background
                    Bitmap bmp = new Bitmap(c.Width, c.Height, g);
                    c.DrawToBitmap(bmp, c.ClientRectangle);
                    g.TranslateTransform(c.Left - Left, c.Top - Top);
                    g.DrawImageUnscaled(bmp, Point.Empty);
                    g.TranslateTransform(Left - c.Left, Top - c.Top);
                    bmp.Dispose();
                }
            }
        }
    }

    public Image Image {
        get { return _image; }
        set {
            _image = value;
            base.RecreateHandle();
        }
    }

    private void refresher_Tick(object sender, System.EventArgs e)
    {
        base.RecreateHandle();
        refresher.Stop();
    }
}

Try it out, & see for yourself i guess :P

试试吧,你自己看吧,我猜是P。

ps: I'm not a guru, so expect all kinds of mistakes in both the C#, & VB.NET versions. lol

ps:我不是专家,所以在c#和VB中都可以看到各种各样的错误。净的版本。哈哈

#5


3  

If you are displaying png with transparence in picture box, it will be automatically take transparence into account, so you have no need to set transparent color

如果你在图片框中显示的是透明的png,它会自动将透明度考虑进去,所以你不需要设置透明的颜色。

#6


1  

The above answers seem to solve your problem. You are indeed seeing what's behind the picture box control - the form itself with backColor white. I have here created a simple function that first converts an image of byte type (array) into a bitmap and thereafter setting specific colors (from the bitmap pic) to transparent. Something you might as well use:

以上答案似乎能解决你的问题。你确实看到了图片框控件背后的东西——用背景色白色的形式。我在这里创建了一个简单的函数,它首先将字节类型(数组)的图像转换为位图,然后将特定的颜色(从位图pic)设置为透明。你可以用的东西:

 using System;
   using System.Drawing;
   using System.Drawing.Imaging;
   using System.Windows.Forms;
    public void LogoDrawTransparent(PaintEventArgs e)
    {
        // Create a Bitmap object from an image file.
        Image myImg;
        Bitmap myBitmap;

        try
        {
            myImg = cls_convertImagesByte.GetImageFromByte(newImg);
            myBitmap = new Bitmap(myImg); // @"C:\Temp\imgSwacaa.jpg");  

            // Get the color of a background pixel.
            Color backColor = myBitmap.GetPixel(0, 0); // GetPixel(1, 1); 
            Color backColorGray = Color.Gray;
            Color backColorGrayLight = Color.LightGray;
            Color backColorWhiteSmoke = Color.WhiteSmoke;
            Color backColorWhite = Color.White;
            Color backColorWheat = Color.Wheat;

            // Make backColor transparent for myBitmap.
            myBitmap.MakeTransparent(backColor);
                    // OPTIONALLY, you may make any other "suspicious" back color transparent (usually gray, light gray or whitesmoke)
            myBitmap.MakeTransparent(backColorGray);
            myBitmap.MakeTransparent(backColorGrayLight);
            myBitmap.MakeTransparent(backColorWhiteSmoke);

            // Draw myBitmap to the screen.
            e.Graphics.DrawImage(myBitmap, 0, 0, pictureBox1.Width, pictureBox1.Height); //myBitmap.Width, myBitmap.Height);
        }
        catch
        {
            try { pictureBox1.Image = cls_convertImagesByte.GetImageFromByte(newImg); }
            catch { } //must do something
        }
    }

You may fire this func on Paint of the pictureBox. This is my class that is referenced n the function above:

你可以把这个func放在图片框的油漆上。这是我的类,它引用了上面的函数:

    class cls_convertImagesByte
{

    public static Image GetImageFromByte(byte[] byteArrayIn)
    {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms);
        return returnImage;
    }

    public static byte[] GetByteArrayFromImage(System.Drawing.Image imageIn)
    {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
        return ms.ToArray();
    }
}

Thanks. Chagbert

谢谢。Chagbert

#1


20  

It probably works perfectly. You are seeing what's behind the picture box control. Which is the form. Whose BackColor is probably white. You can set the form's BackgroundImage property to be sure, you should see the image through the picture box. Like this:

它可能完全工作。你看到的是图片框控件背后的内容。这是表单。他的背景颜色可能是白色的。您可以设置表单的BackgroundImage属性以确定,您应该通过图片框看到图像。是这样的:

c#图片框透明背景似乎不起作用。

Punching a hole through both the picture box and the form requires a bigger weapon, Form.TransparencyKey

在图片框和窗体上打一个洞,需要一个更大的武器。

#2


37  

If you want to overlay images over images (and not images over form), this would make the trick:

如果你想要在图像上覆盖图像(而不是图像),这将是一个技巧:

overImage.Parent = backImage;
overImage.BackColor = Color.Transparent;
overImage.Location = thePointRelativeToTheBackImage;

Where overImage and backImage are PictureBox with png (with transparent background).

其中,overImage和backImage是带有png(具有透明背景)的图片框。

This is because, as said before, the transparency of an image is rendered using the back color of the Parent container. PictureBoxes haven't a "Parent" property so you have to make it manually (or create a cutom control of course).

这是因为,如前所述,图像的透明性是使用父容器的后颜色来呈现的。图片框没有“父”属性,所以您必须手动创建它(或者创建一个cutom控件)。

#3


12  

There's an excellent solution on the CodeProject website at

CodeProject网站上有一个很好的解决方案。

Making Transparent Controls - No Flickering

做透明的控制——不要闪烁。

essentially the trick is to override the paintbackground event so as to loop through all the controls underlying the picturebox and redraw them. The function is:-

本质上,技巧是覆盖paintbackground事件,以便循环遍历图片框背后的所有控件并重新绘制它们。功能:-

protected override void OnPaintBackground(PaintEventArgs e)
       // Paint background with underlying graphics from other controls
   {
       base.OnPaintBackground(e);
       Graphics g = e.Graphics;

       if (Parent != null)
       {
           // Take each control in turn
           int index = Parent.Controls.GetChildIndex(this);
           for (int i = Parent.Controls.Count - 1; i > index; i--)
           {
               Control c = Parent.Controls[i];

               // Check it's visible and overlaps this control
               if (c.Bounds.IntersectsWith(Bounds) && c.Visible)
               {
                   // Load appearance of underlying control and redraw it on this background
                   Bitmap bmp = new Bitmap(c.Width, c.Height, g);
                   c.DrawToBitmap(bmp, c.ClientRectangle);
                   g.TranslateTransform(c.Left - Left, c.Top - Top);
                   g.DrawImageUnscaled(bmp, Point.Empty);
                   g.TranslateTransform(Left - c.Left, Top - c.Top);
                   bmp.Dispose();
               }
           }
       }
   }

#4


4  

I know your Question is founded in C#, but due to the similarity, & ease of conversion from VB.NET, I'll add a full VB version that also allows updating of the control's background as you move it around.

我知道您的问题是在c#中创建的,但是由于相似,并且容易从VB中转换。NET,我将添加一个完整的VB版本,当你移动它时,它还允许更新控件的背景。

You already have an answer, but this is for others who find this post by search engines, & would like a VB version, or simply want to find a FULL convertible sample if they also need it in C#.

你已经有了答案,但这是给那些通过搜索引擎找到这篇文章的人的,他们想要一个VB版本的,或者想要找到一个完全可转换的样本,如果他们还需要c#的话。

Create a new Custom Control Class, & paste the following into it... overwriting the default class stuff:

创建一个新的自定义控件类,并将以下内容粘贴到它…覆盖默认的类:

Custom Control Class:

自定义控件类:

Public Class TransparentPictureBox
    Private WithEvents refresher As Timer
    Private _image As Image = Nothing

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        refresher = New Timer()
        'refresher.Tick += New EventHandler(AddressOf Me.TimerOnTick)
        refresher.Interval = 50
        refresher.Start()

    End Sub

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H20
            Return cp
        End Get
    End Property

    Protected Overrides Sub OnMove(ByVal e As EventArgs)
        MyBase.OnMove(e)
        MyBase.RecreateHandle()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here
        If _image IsNot Nothing Then
            e.Graphics.DrawImage(_image, CInt(Width / 2) - CInt(_image.Width / 2), CInt(Height / 2) - CInt(_image.Height / 2))
        End If
    End Sub


    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
        ' Paint background with underlying graphics from other controls
        MyBase.OnPaintBackground(e)
        Dim g As Graphics = e.Graphics

        If Parent IsNot Nothing Then
            ' Take each control in turn
            Dim index As Integer = Parent.Controls.GetChildIndex(Me)
            For i As Integer = Parent.Controls.Count - 1 To index + 1 Step -1
                Dim c As Control = Parent.Controls(i)

                ' Check it's visible and overlaps this control
                If c.Bounds.IntersectsWith(Bounds) AndAlso c.Visible Then
                    ' Load appearance of underlying control and redraw it on this background
                    Dim bmp As New Bitmap(c.Width, c.Height, g)
                    c.DrawToBitmap(bmp, c.ClientRectangle)
                    g.TranslateTransform(c.Left - Left, c.Top - Top)
                    g.DrawImageUnscaled(bmp, Point.Empty)
                    g.TranslateTransform(Left - c.Left, Top - c.Top)
                    bmp.Dispose()
                End If
            Next
        End If
    End Sub

    Public Property Image() As Image
        Get
            Return _image
        End Get
        Set(value As Image)
            _image = value
            MyBase.RecreateHandle()
        End Set
    End Property

    Private Sub refresher_Tick(sender As Object, e As System.EventArgs) Handles refresher.Tick
        MyBase.RecreateHandle()
        refresher.Stop()
    End Sub
End Class

...save the class, then clean your project, & build again. The new control should appear as a new tool Item. Find it, & drag it to your form.

…保存类,然后清理您的项目,并重新构建。新的控件应该作为一个新的工具项出现。找到它,并把它拖到你的表单上。

I have had issues with this control though... It happens when I try to load an animated "Loading" .gif image.

我对这个控制有些问题……当我尝试加载一个动画“加载”.gif图像时,它就会发生。

The image does not animate, & also has display problems when you hide the control, then try to display it again.

图像没有动画效果,当您隐藏控件时也会显示问题,然后尝试再次显示它。

Sort those issues out, & you'll have a perfect Custom Control Class. :)

解决这些问题,你将拥有一个完美的自定义控件类。:)

EDIT:

编辑:

I have no idea if the following will work in C#'s IDE or not, but here's my attempt at conversion:

我不知道下面是否会在c#的IDE中工作,但是我尝试转换:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class TransparentPictureBox
{
    private Timer withEventsField_refresher;
    private Timer refresher {
        get { return withEventsField_refresher; }
        set {
            if (withEventsField_refresher != null) {
                withEventsField_refresher.Tick -= refresher_Tick;
            }
            withEventsField_refresher = value;
            if (withEventsField_refresher != null) {
                withEventsField_refresher.Tick += refresher_Tick;
            }
        }
    }

    private Image _image = null;

    public TransparentPictureBox()
    {
        // This call is required by the designer.
        InitializeComponent();

        // Add any initialization after the InitializeComponent() call.
        refresher = new Timer();
        //refresher.Tick += New EventHandler(AddressOf Me.TimerOnTick)
        refresher.Interval = 50;
        refresher.Start();

    }

    protected override CreateParams CreateParams {
        get {
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | 0x20;
            return cp;
        }
    }

    protected override void OnMove(EventArgs e)
    {
        base.OnMove(e);
        base.RecreateHandle();
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        base.OnPaint(e);

        //Add your custom paint code here
        if (_image != null) {
            e.Graphics.DrawImage(_image, Convert.ToInt32(Width / 2) - Convert.ToInt32(_image.Width / 2), Convert.ToInt32(Height / 2) - Convert.ToInt32(_image.Height / 2));
        }
    }


    protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
    {
        // Paint background with underlying graphics from other controls
        base.OnPaintBackground(e);
        Graphics g = e.Graphics;

        if (Parent != null) {
            // Take each control in turn
            int index = Parent.Controls.GetChildIndex(this);
            for (int i = Parent.Controls.Count - 1; i >= index + 1; i += -1) {
                Control c = Parent.Controls(i);

                // Check it's visible and overlaps this control
                if (c.Bounds.IntersectsWith(Bounds) && c.Visible) {
                    // Load appearance of underlying control and redraw it on this background
                    Bitmap bmp = new Bitmap(c.Width, c.Height, g);
                    c.DrawToBitmap(bmp, c.ClientRectangle);
                    g.TranslateTransform(c.Left - Left, c.Top - Top);
                    g.DrawImageUnscaled(bmp, Point.Empty);
                    g.TranslateTransform(Left - c.Left, Top - c.Top);
                    bmp.Dispose();
                }
            }
        }
    }

    public Image Image {
        get { return _image; }
        set {
            _image = value;
            base.RecreateHandle();
        }
    }

    private void refresher_Tick(object sender, System.EventArgs e)
    {
        base.RecreateHandle();
        refresher.Stop();
    }
}

Try it out, & see for yourself i guess :P

试试吧,你自己看吧,我猜是P。

ps: I'm not a guru, so expect all kinds of mistakes in both the C#, & VB.NET versions. lol

ps:我不是专家,所以在c#和VB中都可以看到各种各样的错误。净的版本。哈哈

#5


3  

If you are displaying png with transparence in picture box, it will be automatically take transparence into account, so you have no need to set transparent color

如果你在图片框中显示的是透明的png,它会自动将透明度考虑进去,所以你不需要设置透明的颜色。

#6


1  

The above answers seem to solve your problem. You are indeed seeing what's behind the picture box control - the form itself with backColor white. I have here created a simple function that first converts an image of byte type (array) into a bitmap and thereafter setting specific colors (from the bitmap pic) to transparent. Something you might as well use:

以上答案似乎能解决你的问题。你确实看到了图片框控件背后的东西——用背景色白色的形式。我在这里创建了一个简单的函数,它首先将字节类型(数组)的图像转换为位图,然后将特定的颜色(从位图pic)设置为透明。你可以用的东西:

 using System;
   using System.Drawing;
   using System.Drawing.Imaging;
   using System.Windows.Forms;
    public void LogoDrawTransparent(PaintEventArgs e)
    {
        // Create a Bitmap object from an image file.
        Image myImg;
        Bitmap myBitmap;

        try
        {
            myImg = cls_convertImagesByte.GetImageFromByte(newImg);
            myBitmap = new Bitmap(myImg); // @"C:\Temp\imgSwacaa.jpg");  

            // Get the color of a background pixel.
            Color backColor = myBitmap.GetPixel(0, 0); // GetPixel(1, 1); 
            Color backColorGray = Color.Gray;
            Color backColorGrayLight = Color.LightGray;
            Color backColorWhiteSmoke = Color.WhiteSmoke;
            Color backColorWhite = Color.White;
            Color backColorWheat = Color.Wheat;

            // Make backColor transparent for myBitmap.
            myBitmap.MakeTransparent(backColor);
                    // OPTIONALLY, you may make any other "suspicious" back color transparent (usually gray, light gray or whitesmoke)
            myBitmap.MakeTransparent(backColorGray);
            myBitmap.MakeTransparent(backColorGrayLight);
            myBitmap.MakeTransparent(backColorWhiteSmoke);

            // Draw myBitmap to the screen.
            e.Graphics.DrawImage(myBitmap, 0, 0, pictureBox1.Width, pictureBox1.Height); //myBitmap.Width, myBitmap.Height);
        }
        catch
        {
            try { pictureBox1.Image = cls_convertImagesByte.GetImageFromByte(newImg); }
            catch { } //must do something
        }
    }

You may fire this func on Paint of the pictureBox. This is my class that is referenced n the function above:

你可以把这个func放在图片框的油漆上。这是我的类,它引用了上面的函数:

    class cls_convertImagesByte
{

    public static Image GetImageFromByte(byte[] byteArrayIn)
    {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms);
        return returnImage;
    }

    public static byte[] GetByteArrayFromImage(System.Drawing.Image imageIn)
    {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
        return ms.ToArray();
    }
}

Thanks. Chagbert

谢谢。Chagbert