C#绘图实现层概念?

我想了很久了。事情是这样的。画图,两层:A层在下,上面显示的是已绘制的;B层在上,是要、正在画的。拿画一条线来说,是需要不停地Clear画板(B层)的,但却不能Clear... 我想了很久了。
事情是这样的。
画图,两层:A层在下,上面显示的是已绘制的;B层在上,是要、正在画的。
拿画一条线来说,是需要不停地Clear画板(B层)的,但却不能Clear之前画的东西(A层)。
MouseDown :
pa = mouse.Location;

MouseMove :
paintPanelB.Clear();
pb = mouse.Location.
paintPanelB.drawLine(pa, pb);

MouseUp :
pb = mouse.Location.
paintPanelA.drawLine(pa, pb);
paintPanelB.Clear();

懂我的意思吧,B层画过程,A层画结果。
但A、B层位置是重叠的,我怎么也没弄出来透过B层看到A层的东西,大概就是透明效果怎么实现?
展开
 我来答
makosharp
推荐于2018-03-05 · TA获得超过676个赞
知道小有建树答主
回答量:188
采纳率:100%
帮助的人:271万
展开全部

不难,顺手给你写了个用于呈现完全透明效果的控件用于模拟layer概念。说明都在注释中。

public class  LayerControl : UserControl
    {
        private Image image;
        private Graphics graphics;
        public LayerControl(int width, int height)
        {
            this.Width = width;
            this.Height = height;
            //建一个新的指定大小的位图
            image = new Bitmap(width, height);
            graphics = Graphics.FromImage(image);
            // 设置空间风格为:双缓冲|减少闪烁|用户绘制
            SetStyle(ControlStyles.OptimizedDoubleBuffer |ControlStyles.AllPaintingInWmPaint |ControlStyles.UserPaint, true);
        }
        // 重写OnPaint,每当绘画时发生
        protected override void OnPaint(PaintEventArgs e)
        {
            //做一张背景透明的位图当做绘制内容
            //若已有Image属性被指定,则画该图
            //由于e的绘制区域总是在变,这里不需要考虑绘制区域,系统会自己算,超出区域的不予以绘制
            //简单刷原理就是,每当系统要绘制时,先画背景,我们自行处理就需要计算应该画哪个区域(多数都是不规则的区域并集)
            //每当OnPaint时,绘制自己的Image图(若属性存在),或者是纯透明的位图以提供完全透明效果
            var bitMap = new Bitmap(image);
            bitMap.MakeTransparent(Color.White);
            image = bitMap;
            //绘制模式指定
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.GammaCorrected;
            //透明色变换
            float[][] mtxItens = {
            new float[] {1,0,0,0,0},
            new float[] {0,1,0,0,0},
            new float[] {0,0,1,0,0},
            new float[] {0,0,0,1,0},
            new float[] {0,0,0,0,1}};
            ColorMatrix colorMatrix = new ColorMatrix(mtxItens);
            ImageAttributes imgAtb = new ImageAttributes();
            imgAtb.SetColorMatrix(colorMatrix,ColorMatrixFlag.Default,ColorAdjustType.Bitmap);
            //画
            g.DrawImage(image,ClientRectangle,0.0f,0.0f,image.Width, image.Height,GraphicsUnit.Pixel, imgAtb);
        }
        //控件背景绘制
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            Graphics g = e.Graphics;
            //以下代码提取控件原来应有的背景(视觉上的位图,可能会包括其他空间的部分图形)到位图,进行变换后绘制
            if (Parent != null)
            {
                BackColor = Color.Transparent;
                //本控件在父控件的子集中的index
                int index = Parent.Controls.GetChildIndex(this);
                for (int i = Parent.Controls.Count - 1; i > index; i--)
                {
                    //对每一个父控件的可视子控件,进行绘制区域交集运算,得到应该绘制的区域
                    Control c = Parent.Controls[i];
                    //如果有交集且可见
                    if (c.Bounds.IntersectsWith(Bounds) && c.Visible)
                    {
                        //矩阵变换
                        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();
                    }
                }
            }
            else
            {
                g.Clear(Parent.BackColor);
                g.FillRectangle(new SolidBrush(Color.FromArgb(255, Color.Transparent)), this.ClientRectangle);
            }
        }
        //示例代码,请自行修改。
        //在此控件上的绘图工作请写在此处。
        public void DrawCircles()
        {
            using (Brush b = new SolidBrush(Color.Red))
            {
                using (Pen p = new Pen(Color.Green, 3))
                {
                    this.graphics.DrawEllipse(p, 50, 40, 30, 30);
                }
            }
        }
        //示例代码,请自行修改。
        public void DrawRectangle()
        {
            using (Brush b = new SolidBrush(Color.Red))
            {
                using (Pen p = new Pen(Color.Red, 3))
                {
                    this.graphics.DrawRectangle(p, 50, 50, 40, 40);
                }
            }
        }
        //Image属性,每当赋值会引发Invalidate
        public Image Image
        {
            get
            {
                return image;
            }
            set
            {
                image = value;
                
                this.Invalidate();
            }
        }
    }

中间涉及的知识比较多,你可以暂时先不理会。使用时:

             LayerControl lc1 = new LayerControl(100, 100);
            lc1.Location = new Point(20, 20);
            lc1.DrawRectangle();
            LayerControl lc2 = new LayerControl(100, 100);
            lc2.Location = new Point(10, 10);
            lc2.DrawCircles();
            LayerControl lc3 = new LayerControl(100, 100);
            lc3.Location = new Point(0, 0);
            lc3.Image = new Bitmap(@"C:\Users\Mako\Pictures\1.jpg");
            this.Controls.Add(lc1);
            this.Controls.Add(lc2);
            this.Controls.Add(lc3);

得到的是三层图像,其中lc1在顶层,lc3在底层。

如果自己要在lc上画图,请去LayerControl里自己写好要用的方法,切勿在外部使用lc.CreateGraphics()绘图,那样做会导致窗体移动、窗体缩放等操作后引发重绘丢失你刚画的图。


上海华然企业咨询
2024-10-21 广告
上海华然企业咨询有限公司专注于AI与数据合规咨询服务。我们的核心团队来自头部互联网企业、红圈律所和专业安全服务机构。凭借深刻的AI产品理解、上百个AI产品的合规咨询和算法备案经验,为客户提供专业的算法备案、AI安全评估、数据出境等合规服务,... 点击进入详情页
本回答由上海华然企业咨询提供
du瓶邪
推荐于2016-08-31 · TA获得超过2.4万个赞
知道大有可为答主
回答量:1.7万
采纳率:100%
帮助的人:2982万
展开全部
层就是你自己定义的一套图形的管理类!
比如你可以让三角形在层1,四边形在层2,绘制的时候先画层1中所有图元,再画层2中的。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式