首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用图形、C#时没有足够的内存存储图片

使用图形、C#时没有足够的内存存储图片
EN

Stack Overflow用户
提问于 2018-12-13 05:15:32
回答 2查看 254关注 0票数 0

代码非常简单:我按下按钮,图片就会加载到PictureBox中。

代码语言:javascript
运行
复制
    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.FromImage上没有足够的内存。不管我怎么处理这个时间表。示例:

代码语言:javascript
运行
复制
    using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
    g.Clear(Color.FromArgb(0, 255, 255, 255));
    pictureBox1.Invalidate();
}

问题是,为什么在将图片上传到PictureBox之前,我可以使用Graphics做任何我想做的事情:剪切、填充、绘制;但在上传图片之后,我不能这样做?附注:图片尝试了不同的尺寸。同样的图片在上传之前有效(它已经在默认的pictureBox中),并且在上传到pictureBox之后不起作用。走了相当多的论坛关于这个主题,但我的案例(或最相似的案例)找不到。

EN

回答 2

Stack Overflow用户

发布于 2018-12-13 18:18:15

所以问题出现在Graphics.FromImage使用的流中。Documentation说,从Graphics.FromImage打开的流必须在处理图像的整个过程中保持打开。好的,我们可以使用MemoryStream:

代码语言:javascript
运行
复制
    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也能工作)

票数 1
EN

Stack Overflow用户

发布于 2018-12-13 17:58:41

您有3种选择:

1)在不克隆的情况下分配Image.FromStream()结果: PictureBox控件更喜欢在基础流上独立操作(请参阅.Net Source about the PictureBox.Load()方法)。

代码语言:javascript
运行
复制
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块内的所有操作。此时,该流仍然有效:

代码语言:javascript
运行
复制
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()方法。

代码语言:javascript
运行
复制
    pictureBox1.Load(FullName);

所有方法最终都将使用PictureBox控件内部InstallNewImage() (.Net源)方法。查看图像stream是如何处理的。

调用Graphics.FromImage()将不再引发异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53751461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档