2013-07-16 33 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); 
相關問題