为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
千巷猫影 2022-06-12 15:25:31
代码很简单:我按下按钮,图片被加载到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 图片尝试了不同的尺寸。同一张图片在上传前有效(已经在默认图片框中),上传到图片框后无效。走了很多关于这个主题的论坛,但没有找到我的案例(或最相似的案例)。
查看完整描述

2 回答

?
qq_笑_17

TA贡献1818条经验 获得超7个赞

所以问题出在流中,由 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 的情况下工作)


查看完整回答
反对 回复 2022-06-12
?
慕斯709654

TA贡献1840条经验 获得超5个赞

您有 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()将不再引发异常。


查看完整回答
反对 回复 2022-06-12
  • 2 回答
  • 0 关注
  • 720 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信