简体   繁体   English

清除.Net中的位图

[英]Clear A Bitmap in .Net

I'm using PictureBox control to draw complicated charts, and to optimize for performance i use a cache Bitmap for each layer of the drawing, and draw them on the control image, the upper layers have transparent backgrounds, i need to clear them and redraw on every change. 我正在使用PictureBox控件绘制复杂的图表,并且为了优化性能,我在图形的每一层使用了一个缓存位图,并将它们绘制在控件图像上,上层具有透明背景,我需要清除它们并重绘在每一个变化。

Assuming g instance of Graphics class of the Bitmap, using g.Clear(Color.White) draws a white rectangle over everything and so hiding lower layers, and g.Clear(Color.Transparent) draws Transparent rectangle over, what means doing nothing. 假设使用位图的Graphics类的g实例,则使用g.Clear(Color.White)在所有内容上绘制一个白色矩形,从而隐藏较低的图层,而g.Clear(Color.Transparent)绘制透明矩形,这意味着什么也不做。

Isn't there a way to clear the Bitmap returning it to its original state? 是否没有办法清除位图以使其恢复到原始状态?

private void btn_CancelImage_Click(object sender, EventArgs e)
    {
        DialogResult dialogResult = MessageBox.Show("Cancel and delete this Image?", "Cancel", MessageBoxButtons.YesNo);
        if (dialogResult == DialogResult.Yes)
        {
            ClearImage();
            pictureBox1.Refresh();
        }
        else if (dialogResult == DialogResult.No)
        {
            return;
        }
    }
    public void ClearImage()
    {
        Graphics g = Graphics.FromImage(ImageBitmap);
        g.Clear(Color.White);
    }

This is maybe not the answer you were looking for but I think it is an insteresting alternative to what you have. 这可能不是您要找的答案,但是我认为这是您所拥有的替代品。

Instead of having to draw all the layers upwards from every change, I stack as many layers on top of each other by nesting a number of PictureBoxes into one bottom PictureBox pBox0 : 通过将许多PictureBoxes 嵌套到一个底部的PictureBox pBox0 ,我不必在每次更改时都向上绘制所有图层,而在彼此之上堆叠了尽可能多的图层:

List<PictureBox> Layers = new List<PictureBox>();

private void Form1_Load(object sender, EventArgs e)
{
    Layers.Add(pBox0);
    setUpLayers(pBox0 , 20);  // stacking 20 layers onto the botton one
    timer1.Start();           // simulate changes
}

The stacking is set up like this: 堆栈设置如下:

void setUpLayers(Control parent, int count)
{
    for (int i = 0; i < count; i++)
    {
        PictureBox pb = new PictureBox();
        pb.BorderStyle = BorderStyle.None;
        pb.Size = parent.ClientSize;
        Bitmap bmp = new Bitmap(pb.Size.Width,pb.Size.Height,PixelFormat.Format32bppPArgb);
        pb.Image = bmp;
        pb.Parent = i == 0 ? pBox0 : Layers[i - 1];
        Layers.Add(pb);
    }
}

For best performance I use Format32bppPArgb as the pixel format. 为了获得最佳性能,我使用Format32bppPArgb作为像素格式。

For testing I run a Tick event that randomly draws onto a layer: 为了进行测试,我运行了一个Tick事件,该事件随机绘制到图层上:

Random R = new Random(9);
private void timer1_Tick(object sender, EventArgs e)
{
    int l = R.Next(Layers.Count-1) + 1;

    Bitmap bmp = (Bitmap) Layers[l].Image;
    using (Graphics G = Graphics.FromImage(Layers[l].Image))
    {
        G.Clear(Color.Transparent);
        using (Font font = new Font("Consolas", 33f))
        G.DrawString(l + " " + DateTime.Now.Second , font, Brushes.Gold, 
            R.Next(bmp.Size.Width),  R.Next(bmp.Size.Height));
    }
    Layers[l].Image = bmp;
}

To collect all layers into one Bitmap you would make use of the DrawToBitmap method: 要将所有图层收集到一个位图中,可以使用DrawToBitmap方法:

Bitmap GetComposite(Control ctl)
{
    Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height,
                            PixelFormat.Format32bppArgb);
    ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
    return bmp;
}

The result can then be saved or used in any other way.. 然后可以保存结果或以其他任何方式使用该结果。

Note that creating too many layers this way will hit a limit for window handles; 请注意,以这种方式创建过多的图层将达到窗口句柄的极限。 I hit that limit at around 90 layers. 我达到了大约90层的极限。 If you need more that a few dozen layers a more intricate caching strategy is called for.. 如果您需要几十层以上的存储,则需要更复杂的缓存策略。

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

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