C# Wpf-将画布另存为图像并将图像加载到画布。错误:";正在被另一个过程使用”;
我正在尝试将包含一些形状的画布保存为图像(*.jpg,*.bmp,*.png),然后再次将该图像加载到画布 当我单击“保存按钮”,然后单击“加载按钮”,然后再次单击“保存按钮”时,我出现以下故障: 进程无法访问文件“H:\VisualC\HK5\LT Win\ForTesting\TestSaveCanvasToBitmap\bin\Debug\TestImage.bmp”,因为另一进程正在使用该文件。 似乎有一个文件流处于打开状态,但尚未关闭。 谁能给我解释一下吗 提前谢谢 这是我的密码C# Wpf-将画布另存为图像并将图像加载到画布。错误:";正在被另一个过程使用”;,c#,wpf,canvas,C#,Wpf,Canvas,我正在尝试将包含一些形状的画布保存为图像(*.jpg,*.bmp,*.png),然后再次将该图像加载到画布 当我单击“保存按钮”,然后单击“加载按钮”,然后再次单击“保存按钮”时,我出现以下故障: 进程无法访问文件“H:\VisualC\HK5\LT Win\ForTesting\TestSaveCanvasToBitmap\bin\Debug\TestImage.bmp”,因为另一进程正在使用该文件。 似乎有一个文件流处于打开状态,但尚未关闭。 谁能给我解释一下吗 提前谢谢 这是我的密码 pu
public void SaveImage(Canvas canvas, int width, int height, string filePath)
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(canvas);
double dpi = 96d;
RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, dpi, dpi, System.Windows.Media.PixelFormats.Default);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(canvas);
dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
BmpBitmapEncoder image = new BmpBitmapEncoder();
image.Frames.Add(BitmapFrame.Create(rtb));
using (Stream fs = File.Create(filePath))
{
image.Save(fs);
fs.Close();
}
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
int width = (int)myCanvas.ActualWidth;
int height = (int)myCanvas.ActualHeight;
string filePath = "TestImage.bmp";
SaveImage(myCanvas, width, height, filePath);
}
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
Uri uri = new Uri(@"TestImage.bmp", UriKind.Relative);
BitmapImage bmi = new BitmapImage(uri);
ImageBrush brush = new ImageBrush();
brush.ImageSource = bmi;
myCanvas.Background = brush;
}
该文件仍处于锁定状态,因为您正在笔刷中直接引用它。如果不可靠地再现问题,就不可能确定最佳解决方案是什么。但最有可能的情况是,如果在画笔中使用位图对象之前克隆该对象,当您再次尝试保存到该文件时,它将被释放 例如:
BitmapImage bmi = new BitmapImage(uri).Clone();
不幸的是,我不知道有什么好的确定方法可以强制关闭
BitmapImage
对象,尤其是它对文件的引用。您可以调用Freeze()
,它可能会断开与文件的连接(但我还没有尝试过)。或者,强制垃圾收集应该可以工作(即调用GC.Collect()
)。当您加载映像并试图通过覆盖来保存它时,引用其物理文件的映像仍被应用程序使用,因此无法覆盖该文件。我猜当您从URI创建BitmapImage
对象时,附加到文件的流总是打开的。尝试像这样更改加载方法
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
MemoryStream memoStream = new MemoryStream();
using (FileStream fs = File.OpenRead("TestImage.bmp"))
{
fs.CopyTo(memoStream);
BitmapImage bmi = new BitmapImage();
bmi.BeginInit();
bmi.StreamSource = memoStream;
bmi.EndInit();
ImageBrush brush = new ImageBrush(bmi);
myCanvas.Background = brush;
fs.Close();
}
}
我们的想法是将文件流复制到内存流,这样图像对象将生活在内存中,不再依赖文件。谢谢您的帮助。我已经用另一种方法解决了我的问题。很好的解释。我已经用这个解决了我的问题,谢谢。把这个记下来作为一个答案吧?