我正在尝试在相机的照片上添加一些文本,这是我正在使用的方法,但不幸的是我得到了一个closedStream错误,或者当我尝试使用时有跨线程访问调度员。有人可以解释一下我出了什么问题吗?
void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)
{
DateTime dt = DateTime.Now;
string fileName = dt.Year.ToString() + dt.Month.ToString() + dt.Day.ToString() + dt.Hour.ToString() + dt.Minute.ToString() + dt.Second.ToString() + ".jpg";
try
{
// Save picture to the library camera roll.
library.SavePictureToCameraRoll(fileName, e.ImageStream);
// Set the position of the stream back to start
e.ImageStream.Seek(0, SeekOrigin.Begin);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// load photo to writable bitmap
WriteableBitmap writeableBitmap = PictureDecoder.DecodeJpeg(e.ImageStream);
writeableBitmap.Invalidate();
var renderText = new TextBlock
{
Text = "Hello World",
FontSize = 72,
Foreground = new SolidColorBrush(Colors.White),
FontWeight = FontWeights.Black,
Width = 500,
Height = 100
};
writeableBitmap.Render(renderText, new TranslateTransform() { X = 100, Y = 300 });
writeableBitmap.Invalidate();
using (var ms = new MemoryStream())
{
writeableBitmap.SaveJpeg(ms, 1024, 768, 0, 100);
ms.Seek(0, SeekOrigin.Begin);
library.SavePicture("x" + fileName, ms);
}
// e.ImageStream.Close();
});
// Save picture as JPEG to isolated storage.
using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream targetStream = isStore.OpenFile(fileName, FileMode.Create, FileAccess.Write))
{
// Initialize the buffer for 4KB disk pages.
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
// Copy the image to isolated storage.
while ((bytesRead = e.ImageStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
targetStream.Write(readBuffer, 0, bytesRead);
}
}
}
}
finally
{
// Close image stream
e.ImageStream.Close();
}
}
使用上面的代码我收到以下错误:无法访问已关闭的流。
如果我删除Dispatcher,我会收到此错误:无效的跨线程访问。
感谢。
答案 0 :(得分:0)
在调度员范围之外放置更少的代码。
或将e.ImageStream保存到其他流可以在调度程序范围内获取。
答案 1 :(得分:0)
首先,发生了什么?
Dispatcher.BeginInvoke
推迟了你的代码并告诉UI线程只要它可用就执行它。因此,您的e.ImageStream.Close();
行会在BeginInvoke
内的代码之前执行。因此,当您尝试读取流的内容时,它已经关闭。
解决这个问题的两种方法:
e.ImageStream.Close();
块中删除finally
。但我不知道该流是否会保持开放状态。如果1.不起作用,请将流的内容复制到MemoryStream
,然后使用此流创建WriteableBitmap
:
var stream = new MemoryStream();
e.ImageStream.CopyTo(stream);
在这两种情况下,请勿忘记在创建WriteableBitmap
后关闭流。