在picturebox上绘制位图背景的内存不足错误

时间:2014-07-31 17:18:42

标签: c# bitmap background-image image-rotation

这是我的问题:

在50ms的时间标记上重复该方法。 从程序的启动到及时转发,这个过程的RAM内存不断增长,最后调试器抛出了内存错误"到粗体线(drawimage方法)。

有没有人可以帮助我找到解决方案以避免这种情况并解释为什么会发生这种情况?

PS。我的目标是不断旋转图片框的背景图像。我知道也许我可以直接在表格上绘图而不是在pictureBox上绘图,但如果有一个PictureBox的解决方案,我会很高兴:p

谢谢!

public static Bitmap RotateImage(Image image, PointF offset, float angle)
    {
        if (image == null)
            throw new ArgumentNullException("image");

        //create a new empty bitmap to hold rotated image
        Bitmap rotatedBmp = new Bitmap(image.Width, image.Height);
        rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        //make a graphics object from the empty bitmap
        Graphics g = Graphics.FromImage(rotatedBmp);

        //Put the rotation point in the center of the image
        g.TranslateTransform(offset.X, offset.Y);

        //rotate the image
        g.RotateTransform(angle);

        //move the image back
        g.TranslateTransform(-offset.X, -offset.Y);

        //draw passed in image onto graphics object
        **g.DrawImage(image, new PointF(0, 0));**

        return rotatedBmp;
    }

3 个答案:

答案 0 :(得分:2)

你也需要Dispose()旧的位图。

想象一下你的代码看起来像这样:

public static Bitmap RotateImage(Image image, PointF offset, float angle)
{
    if (image == null)
        throw new ArgumentNullException("image");

    //create a new empty bitmap to hold rotated image
    Bitmap rotatedBmp = new Bitmap(image.Width, image.Height);
    rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);
    return rotatedBmp;
}

我尝试在循环中调用你的函数,但它仍然失败了!我不得不自己处理位图。我不清楚为什么.NET不能清理它们。

Image img = new Bitmap(@"some_image.png");
PointF p = new PointF(0,0);
for (int i=0; i<5000; i++)
{
    Bitmap b = RotateImage(img, p, i % 360);
    b.Dispose(); // Fails if you don't do this!
}

答案 1 :(得分:1)

您的图形永远不会丢失,因此您正在泄漏内存。我认为你应该在绘制之后处理图形,

g.Dispose()

你可能应该阅读一下Idisposable,以避免将来出现这个问题,

答案 2 :(得分:1)

这是解决方案!!!

我已经处理了picturebox的backgroundimage和我每次创建的位图!

感谢大家!

    private void timer1_Tick(object sender, EventArgs e)
    {
        Image oldImage = RotateImage(
            pb_logoAfterLoad.BackgroundImage,
            offsetPoint,
            20);

        pb_logoAfterLoad.BackgroundImage.Dispose();
        pb_logoAfterLoad.BackgroundImage = (Image)oldImage.Clone();

        oldImage.Dispose();

    }