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层的东西,大概就是透明效果怎么实现? 展开
事情是这样的。
画图,两层: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层的东西,大概就是透明效果怎么实现? 展开
展开全部
不难,顺手给你写了个用于呈现完全透明效果的控件用于模拟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 广告
2024-10-21 广告
上海华然企业咨询有限公司专注于AI与数据合规咨询服务。我们的核心团队来自头部互联网企业、红圈律所和专业安全服务机构。凭借深刻的AI产品理解、上百个AI产品的合规咨询和算法备案经验,为客户提供专业的算法备案、AI安全评估、数据出境等合规服务,...
点击进入详情页
本回答由上海华然企业咨询提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询