我试图将包含某些形状的画布保存为图像(* .jpg,* .bmp,* .png)并再次将该图像加载到画布。
当我点击"保存按钮"然后我点击"加载按钮"然后我点击了"保存按钮"再次,我有以下错误:
进程无法访问文件' H:\ VisualC \ HK5 \ LT Win \ ForTesting \ TestSaveCanvasToBitmap \ bin \ Debug \ TestImage.bmp'因为它正被另一个进程使用。
似乎有一个文件流已打开但尚未关闭。 有人可以帮我解释一下吗?
提前致谢!
这是我的代码
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;
}
答案 0 :(得分:0)
文件仍处于锁定状态,因为您直接在画笔中引用它。如果没有a good, minimal, complete code example可靠地再现问题,就无法确定最佳解决方案是什么。但最有可能的是,如果您只是在刷子中使用它之前克隆位图对象,那么当您再次尝试保存到该文件时,它将被释放。
例如:
BitmapImage bmi = new BitmapImage(uri).Clone();
不幸的是,我不知道强制BitmapImage
对象的良好的确定性方法,特别是它对文件的引用是关闭的。您可以致电Freeze()
,它会与文件断开连接(但我还没有尝试过)。或者,强制垃圾收集应该起作用(即调用GC.Collect()
)。
答案 1 :(得分:0)
加载图像并尝试通过覆盖保存图像时,应用程序仍会使用引用其物理文件的图像,因此无法覆盖该文件。我想当你从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();
}
}
我们的想法是将文件流复制到内存流中,这样您的图像对象就会存在于不再依赖于文件的内存中。