代码很简单:我按下按钮,图片就会加载到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.FromImage上没有足够的内存。无论我用这个时间表做什么。示例:
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.Clear(Color.FromArgb(0, 255, 255, 255));
pictureBox1.Invalidate();
}
问题是,为什么在将图片上传到PictureBox之前,我可以用Graphics做任何我想做的事情:剪切、填充、绘制;但上传照片后我不能?图片尝试了不同的尺寸。相同的图片在上传之前可以工作(它已经在默认的pictureBox中(,在上传到pictureBox后不工作。在这个话题上浏览了很多论坛,但没有找到我的案例(或最相似的案例(。
所以问题出在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));
}
}
还有形象。Clone((需要删除,因为流必须具有对同一映像的引用,而不是对其副本的引用才能进行正确的工作。(老实说,这个简单的程序可以在没有MemoryStream的情况下工作(
您有三种选择:
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()
将不再引发异常