猿问

使用Graphics时图片内存不足,C#

代码很简单:我按下按钮,图片被加载到PictureBox中。


    private void button1_Click(object sender, EventArgs e)

{

        using (FileStream stream = File.OpenRead(FullName))

        {

            pictureBox1.Image = (Bitmap)Bitmap.FromStream(stream).Clone();

            stream.Close();

            stream.Dispose();

        }

}

但是当我从其他函数\事件中使用 PictureBox'e 上的 Graphics 时,它发誓在 Graphics.FromImage 上没有足够的内存。不管我用这个时间表做什么。例子:


    using (Graphics g = Graphics.FromImage(pictureBox1.Image))

{

    g.Clear(Color.FromArgb(0, 255, 255, 255));

    pictureBox1.Invalidate();

}

问题是,为什么我可以在将图片上传到 PictureBox 之前对 Graphics 做任何我想做的事情:剪切、填充、绘制;但是上传图片后我不能?ps 图片尝试了不同的尺寸。同一张图片在上传前有效(已经在默认图片框中),上传到图片框后无效。走了很多关于这个主题的论坛,但没有找到我的案例(或最相似的案例)。


千巷猫影
浏览 721回答 2
2回答

qq_笑_17

所以问题出在流中,由 Graphics.FromImage 使用。文档说,从 Graphics.FromImage 打开的流必须在整个使用图像的过程中保持打开状态。好的,我们可以使用 MemoryStream:    MemoryStream ms;private void button1_Click(object sender, EventArgs e){    ms = new MemoryStream();    using (FileStream stream = File.OpenRead(FullName))    {        stream.CopyTo(ms);        pictureBox1.Image = Bitmap.FromStream(ms);    }}        private void button2_Click(object sender, EventArgs e){    using (Graphics g = Graphics.FromImage(pictureBox1.Image))    {        g.Clear(Color.FromArgb(0, 255, 255, 255));    }     }并且 image.Clone() 需要删除,因为流必须具有对同一图像的引用,而不是对其副本的正确工作。(说实话,这个简单的程序可以在没有 MemoryStream 的情况下工作)

慕斯709654

您有 3 种选择:1) 在不克隆的情况下分配Image.FromStream()结果:PictureBox 控件更喜欢在底层流上自行操作(请参阅有关 PictureBox.Load() 方法的 .Net Source)。private void button1_Click(object sender, EventArgs e){    using (FileStream stream = File.OpenRead(FullName))    {        pictureBox1.Image = Bitmap.FromStream(stream);    }    using (Graphics g = Graphics.FromImage(pictureBox1.Image))    {        g.Clear(Color.FromArgb(0, 255, 255, 255));    }}  2) 执行 using 块内的所有操作。此时流仍然有效:using (FileStream stream = File.OpenRead(FullName){    pictureBox1.Image = (Image)Image.FromStream(stream).Clone();    using (Graphics g = Graphics.FromImage(pictureBox1.Image))    {        g.Clear(Color.FromArgb(0, 255, 255, 255));    }}3) 直接使用Load()方法。    pictureBox1.Load(FullName);所有方法最终都将使用 PictureBox 控件内部的InstallNewImage()(.Net 源)方法。看看如何stream处理图像。调用Graphics.FromImage()将不再引发异常。
随时随地看视频慕课网APP
我要回答