繁体   English   中英

C#自定义图片框控件

[英]C# custom picturebox control

我从事的项目需要不断获取位图并将其绘制在图片框上。

这个想法是绘制第一个初始位图,然后检索其余的位图并将它们绘制在初始位图上方。 (第一个仍显示在图片框中,因此我想在第一个位图上绘制它们)。

我试图设计一个自定义控件来实现OnPaint事件,但是第二次触发该事件时,它将绘制第二个block并完全隐藏之前绘制的图像。

public class RapidPictureBox: PictureBox
{
    public pictureBox1Control()
    {
        SetStyle(
          ControlStyles.AllPaintingInWmPaint |
          ControlStyles.OptimizedDoubleBuffer |
          ControlStyles.UserPaint |
          ControlStyles.ResizeRedraw, true);
    }

     public Bitmap block = null;
     public int x = 0, y = 0;
     protected override void OnPaint(PaintEventArgs e)
     {
         e.Graphics.DrawImage(block, x, y);
     }
 }

private void Form1_Load(object sender, EventArgs e)
{  
    RapidPictureBox pictureBox1 = new RapidPictureBox();
    pictureBox1.Dock = DockStyle.Fill;
    Controls.Add(pictureBox1);

    pictureBox1.block = new Bitmap("3.png"); //first initial image

    pictureBox1.block = new Bitmap("2.png"); //draw on the initial one.
}

我不确定代码中有什么问题。 每次需要时,我都会使用e EventArgs绘制一个新块,但新绘制似乎完全隐藏了以前的位图。

您可以从图片框创建图形对象,然后在当前图像上重绘该对象

initial =new Bitmap("test.png");
pictureBox1.Image = initial;
var graphics = pictureBox1.CreateGraphics(); //create a graphic objec
graphics.DrawImage(block, x,y);//that's the second method

您应该做的是将新图像覆盖在先前图像上。 假设有一个主图像(第一个图像),而您想在该主图像上打印下一个图像(重叠图像)。 使用以下方法可以做到这一点。

private Bitmap GetOvelappedImages(Bitmap primaryImage, Bitmap overlappingImage)
{
 //create graphics from main image
 using (Graphics g = Graphics.FromImage(primaryImage))
 {
    //draw other image on top of main Image
     g.DrawImage(overlappingImage, new Point(0, 0));
 }
 return primaryImage;
}

然后将此新图像设置为pictureBox1.block。

private void Form1_Load(object sender, EventArgs e)
{  
    RapidPictureBox pictureBox1 = new RapidPictureBox();
    pictureBox1.Dock = DockStyle.Fill;
    Controls.Add(pictureBox1);

    pictureBox1.block = GetOverlappedImages(new Bitmap("3.png"),new Bitmap("2.png")); //draw on the initial one.
}

那应该为您工作。

注意:使用图像后,应将其丢弃。

更新:您需要重新绘制整个图像,因为仅当需要重画图片框上显示的当前图像时才调用OnPaint。 重写OnPaint方法可在每次绘制表单时重新绘制图像; 否则,图像将一直保留到下一次重新绘制为止。 在这里阅读OnPaint的文档

代码的问题是您没有将图片添加到要替换它们的控件中。

旁注 :使用您拥有的代码,您不会处理PictureBox es图像中设置的Bitmap对象,因此这可能会导致内存泄漏。

您可以创建类似的控件LayeredPictureBox 这将获取所有图像并将它们绘制在彼此之上。 它将具有较差的性能,并且图像将需要具有透明度才能看起来分层,但是您可以理解:

public class LayeredPictureBox : PictureBox
{
    public LayeredPictureBox()
    {
        SetStyle(
          ControlStyles.AllPaintingInWmPaint |
          ControlStyles.OptimizedDoubleBuffer |
          ControlStyles.UserPaint |
          ControlStyles.ResizeRedraw, true);
    }

     public List<Bitmap> blocks = new List<Bitmap>();
     public int x = 0, y = 0;
     protected override void OnPaint(PaintEventArgs e)
     {
         foreach (Bitmap block in blocks)
         {
             e.Graphics.DrawImage(block, x, y);
         }
     }
 }

private void Form1_Load(object sender, EventArgs e)
{  
    RapidPictureBox pictureBox1 = new RapidPictureBox();
    pictureBox1.Dock = DockStyle.Fill;
    Controls.Add(pictureBox1);

    pictureBox1.blocks.Add(new Bitmap("3.png")); //first initial image

    pictureBox1.blocks.Add(new Bitmap("2.png")); //draw on the initial one.
}

另一种选择是在添加所有图像时将它们合并在一起,然后将其绘制到PictureBox中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM