具有透明背景的透明图像问题

时间:2013-12-08 10:48:24

标签: c# winforms

我在显示透明背景的透明图像时遇到问题。透明背景采用底层控件的颜色,这很好......问题是底层背景上的一些细节(线条)正在覆盖图像,如下图所示。

这是我正在使用的代码....这是笔记的代码....

    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();
        }


    }
}

这是基础控制的代码......音乐人员

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#不能很好地处理透明度...... 任何帮助将不胜感激..

2 个答案:

答案 0 :(得分:1)

两个错误。 PictureBox支持透明图像,只要将其BackColor属性设置为Color.Transparent即可。你为MusicStaff做了哪些但没有为MusicNote做过。分层透明不起作用,你不需要MusicStaff透明,只需要图片框。

通过要求Parent将自身绘制到控件中以提供背景像素来模拟这种透明度。这是你的第二个错误,你在DrawLines()方法中使用CreateGraphics()。它直接绘制到屏幕上,而不是控制界面。你必须在这里使用pea.Graphics。

请注意,使用PictureBox获得的增值是非常低的。控件很昂贵,你可以很容易地烧掉数百个来显示一张音乐。你会注意到,涂漆本身会很慢。你可以通过让MusicStaff只是自己绘制笔记来避免这种情况,使用Graphics.DrawImage()来完成工作。透明效果现在也变得更加简单,只是油漆层。这是WPF的方式。您需要处理的唯一不便是鼠标命中测试不再那么简单,您需要将面板的MouseDown事件坐标映射到注释。只需保留一个列表,跟踪每个音符的显示位置。您将使用它进行绘画以及鼠标命中测试。

答案 1 :(得分:1)

在基础控件“Mus​​icStaff”

的子级中添加顶级控件“Mus​​icNote”

之后的事情 - 初始化所有组件 -

// mStaff: the MusicStaff object
// mNote: the MusicNote object
mStaff.Children.Add(mNote);

在旧方案中,表单是两者的父级,因此它们在任何透明区域中显示表单背景

修改“MusicNote”的父级后,它会在透明区域中显示“MusicStaff”背景

我希望有所帮助!