2013-07-16 32 views
0

我试图放置一个没有明确形状的图像(例如一顶帽子)在不同的图像控件上。 问题在于,由于控件具有明确的形状,因此它会保留默认的背景色以覆盖空白处留下的空白。图像控件与图像的大小完全相同。 我试过使用control.BackColor = Color.Transparent;但它似乎并不奏效。 还有其他建议吗?是否可以创建一个非形状的控件?

+2

是图像本身透明?例如,PNG图像支持透明颜色。这对你的工作很重要... –

+0

编辑你的标题。请阅读:http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles – RahulD

+0

我相信这是WinForms,所以你可能想在你的标签中指定这个(相反也许是背景或图片框)。我原本打算在注意到'BackColor'之前回答WPF。 –

回答

1

您可以使用Control.Region用于此目的

GraphicsPath path = new GraphicsPath(); 
path.AddEllipse(control.ClientRectangle); 
control.Region = new Region(path); 

试试这个,你可以使用GraphicsPath创建任何形状并将其设置为Region比如我创建椭圆。

编辑

如果你只是想设置背景色= Color.Transparent。出于某种原因,某些控件不允许这样做。在这种情况下,你可以做以下

public class CustomControl1 : Control 
{ 
    public CustomControl1() 
    { 
     this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
    } 
} 

创建控制的后裔,并设置this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);应该做的伎俩

+0

非常规形状怎么样?像这样:http://img2-2.timeinc.net/people/i/2013/pets/news/130218/cat-monopoly-600.jpg –

+0

如果该图像具有透明背景,则可以将控件的“BackGroundImage”属性和设置Control.BackColor = Color.Transparent; –

+0

为什么Color.Transparent对你不起作用? –

0

如果您Image Control(如PictureBox)不移动(通过按住鼠标下来,在运行时由用户拖动),您可以使用这种技术,使您可以在彼此之上显示图像。这些图像应该有透明的背景:

public class ImageControl : Control { 
    public ImageControl(){ 
     SetStyle(ControlStyles.Opaque, true); 
    } 
    public Image Image {get;set;} 
    protected override CreateParams CreateParams { 
     get { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x20; 
      return cp; 
     } 
    } 
    protected override void OnPaint(PaintEventArgs e){ 
     if(Image != null) e.Graphics.DrawImage(Image, Point.Empty); 
    } 
} 

您可以使用上面,而不是PictureBox控制。在运行时拖动此控件会导致闪烁很多。所以如果你想,所以我认为只有1个解决方案使用Region。在这种方法中,您必须将您的Bitmap设置为Region,并为您的Control.Region属性分配此RegionChris Dunaway给出的链接对你来说很有帮助。不过,我不得不说,Region并没有像你期望的那样平滑的边界。这是缺乏这种方法。为方便起见,我会稍加修改后的代码在这里,该代码使用LockBits它的表现将优于原代码:

public class Util { 
//invert will toggle backColor to foreColor (in fact, I mean foreColor here is the Solid Color which makes your image distinct from the background). 
    public static Region RegionFromBitmap(Bitmap bm, Color backColor, bool invert) 
    { 
     Region rgn = new Region(); 
     rgn.MakeEmpty();//This is very important    
     int argbBack = backColor.ToArgb(); 
     BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
     int[] bits = new int[bm.Width * bm.Height]; 
     Marshal.Copy(data.Scan0, bits, 0, bits.Length); 
     // 
     Rectangle line = Rectangle.Empty; 
     line.Height = 1; 
     bool inImage = false; 
     for (int i = 0; i < bm.Height; i++) 
     { 
      for (int j = 0; j < bm.Width; j++) 
      { 
       int c = bits[j + i * bm.Width]; 
       if (!inImage) 
       { 
        if (invert ? c == argbBack : c != argbBack) 
        { 
         inImage = true; 
         line.X = j; 
         line.Y = i; 
        } 
       } 
       else if(invert ? c != argbBack : c == argbBack) 
       { 
        inImage = false; 
        line.Width = j - line.X; 
        rgn.Union(line); 
       } 
      } 
     } 
     bm.UnlockBits(data); 
     return rgn; 
    } 
} 
//Use the code 
//if your Bitmap is a PNG with transparent background, you can get the Region from it like this: 
Region rgn = Util.RegionFromBitmap(yourPng, Color.FromArgb(0), false); 
//if your Bitmap has a figure with solid color of Black, you can get the Region like this: 
Region rgn = Util.RegionFromBitmap(yourPng, Color.Black, true); 
相关问题