0

我正在尝试在相机拍摄的照片上添加一些文本,这是我正在使用的方法,但不幸的是,我得到了一个 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();
        }
    }

使用上面的代码,我收到以下错误:无法访问已关闭的流。

如果我删除调度程序,我会收到此错误:无效的跨线程访问。

谢谢。

4

2 回答 2

0

首先,发生了什么?

Dispatcher.BeginInvoke推迟你的代码并告诉 UI 线程在它可用时执行它。因此,您的e.ImageStream.Close();行在BeginInvoke. 因此,当您尝试读取流的内容时,它已经关闭。

解决这个问题的两种方法:

  1. e.ImageStream.Close();finally块中删除。但我不知道流是否仍会保持打开状态。
  2. 如果 1. 不起作用,请将流的内容复制到 a MemoryStream,然后使用此流创建WriteableBitmap

    var stream = new MemoryStream();
    e.ImageStream.CopyTo(stream);
    

在这两种情况下,不要忘记在创建完WriteableBitmap.

于 2012-10-25T20:47:05.703 回答
0

将 ui less 代码放置在调度程序范围之外。

或将您的 e.ImageStream 保存到其他流可以在调度程序范围内获得。

于 2012-10-24T01:03:54.927 回答