2013-12-08 228 views
0

我在使用透明背景顯示透明圖像時遇到問題。透明背景採用底層控件的顏色,這很好......但問題是底層背景上的一些細節(線條)正在覆蓋圖像,如下圖所示。 使用透明背景的透明圖像問題

這裏是我使用的代碼....這是音符的代碼....

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Media; 
using System.Drawing; 

namespace Simpe_Piano_new 
{ 
    class MusicNote: PictureBox 
    { 
     public SoundPlayer sp = new SoundPlayer(); 
     Timer tmr = new Timer(); 
     public int pitch;  //The no. of the music key (e.g. the sound freuency). 
     public int noteDuration; //Shape of note. 
     public string noteShape; 

     public MusicNote(int iPitch, int iNoteDuration) 
      : base() 
     { 
      pitch = iPitch; 
      noteDuration = iNoteDuration; 
      Size = new Size(40, 40); 
     } 

     public void ShowNote() 
     { if (this.noteDuration == 1) noteShape = "Quaver.png"; 
      if (this.noteDuration == 4) noteShape = "Crotchet.png"; 
      if (this.noteDuration == 7) noteShape = "minim.png"; 
      if (this.noteDuration == 10) noteShape = "DotMin.png"; 
      if (this.noteDuration == 12) noteShape = "SemiBreve.png"; 
      this.BackgroundImage = Image.FromFile(noteShape); 
      this.BackColor = Color.Transparent; 
      Location = new Point((pitch * 40) - 40, 100); 
     } 
     protected override void OnPaint(PaintEventArgs pe) 
     { 
      base.OnPaint(pe); 
     } 

     public void PlaySound() 
     { 
      sp.SoundLocation = this.pitch + ".wav"; 
      sp.Play(); 
     } 

     public void StopSound() 
     { 
      sp.SoundLocation = this.pitch + ".wav"; 
      sp.Stop(); 
     } 

     public void Play() 
     { 
      sp.SoundLocation = this.pitch + ".wav"; 
      sp.Play(); 
      //Time to play the duration 
      tmr.Interval = noteDuration; 
      tmr.Start(); 
      tmr.Tick += new System.EventHandler(ClockTick); 
     } 

     void ClockTick(object sender, EventArgs e) 
     { 
      sp.Stop(); 
      tmr.Stop(); 
     } 


    } 
} 

這是底層control..the音樂工作人員的代碼

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Windows.Forms; 

namespace Simpe_Piano_new 
{ 
    public class MusicStaff: Panel 
    { 
     Pen myPen; 
     Graphics g; 

     public MusicStaff() 
     { 
      this.Size = new Size(1000, 150); 
      this.Location = new Point(0, 0); 
      this.BackColor = Color.Transparent; 
      this.Paint += new PaintEventHandler(DrawLines); 
     } 

     private void DrawLines(object sender, PaintEventArgs pea) 
     { 
      myPen = new Pen(Color.Black, 1); 
      g = this.CreateGraphics(); 
      for (int i = 1; i < 6; i++) 
      { 
       g.DrawLine(myPen, 0, (this.Height/6) * i, this.Width, (this.Height/6) * i); 
      } 
     } 
    } 
} 

我發現,C#不處理的透明度非常好... 任何幫助將不勝感激..

+1

你確定你的筆記圖片是透明的嗎?你還應該確定你的'MusicNote'的'Parent'應該是'MusicStaff'面板,看起來就像是你的表格,而不是你的面板。 –

+0

是的,我敢肯定,圖像是透明的...我調用另一個類的方法,像這樣mn.ShowNote(); Form1.Ms.Controls.Add(MN);是mn是MusicNote的一個實例,Ms是MusicStaff的實例,因此我認爲父母是MusicStaff .... – user2307236

回答

1

-Initializing所有組件 -

// mStaff: the MusicStaff object 
// mNote: the MusicNote object 
mStaff.Children.Add(mNote); 
在舊方案中

後添加在基礎控制「MusicStaff」

類似的東西的孩子頂部控制面板「MusicNote」,形式是父,因此它們在任何透明區域顯示錶單背景

修改「MusicNote」的父級後,它會在透明區域顯示「MusicStaff」背景

我希望有所幫助!

1

兩個錯誤。 PictureBox支持透明圖像,只要您將其BackColor屬性設置爲Color.Transparent。你爲MusicStaff做的,但不是爲MusicNote做的。分層透明不起作用,你不需要MusicStaff是透明的,只需要圖片框。

這種透明度是通過讓父親將自己繪製成控件來提供背景像素來模擬的。這是你的第二個錯誤,你在你的DrawLines()方法中使用CreateGraphics()。它直接畫到屏幕上,而不是控制表面。你必須在這裏使用pea.Graphics。

請注意,使用PictureBox所獲得的增值是非常低的。控件價格昂貴,您可以輕鬆燒錄數百個音樂來顯示一張音樂。你會注意到,繪畫本身會變得很慢。您可以通過讓MusicStaff僅使用Graphics.DrawImage()來完成作業來避免這種情況。透明效果現在也更加簡單,僅僅是一層油漆。 WPF是這樣做的。您必須面對的唯一不便是鼠標點擊測試不再那麼簡單,您需要將面板的MouseDown事件座標映射到筆記。只要保持一個列表,以便跟蹤每個音符的顯示位置。您將使用它進行繪畫以及鼠標點擊測試。

+0

感謝您的幫助,您的回答非常有幫助。 – user2307236