2012-10-23 40 views
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(); 
     } 
    } 

隨着上面的代碼,我得到以下錯誤:無法訪問封閉的流。

如果我刪除Dispatcher,我得到這個錯誤:無效的跨線程訪問。

謝謝。

+0

沒有調度程序,在哪一行你會得到'無效的跨線程訪問'錯誤? –

+0

這一行:WriteableBitmap writeableBitmap = PictureDecoder.DecodeJpeg(e.ImageStream); – teh0wner

回答

0

將調用範圍以外的代碼放在少量代碼中。

或將您的e.ImageStream保存爲其他流可以在調度程序範圍內獲得。

+0

「或將e.ImageStream保存到調度程序範圍內的其他流中。我將如何實現這一目標? – teh0wner

0

首先,發生了什麼?

Dispatcher.BeginInvoke推遲你的代碼,並告訴UI線程在它可用時執行它。因此,您的e.ImageStream.Close();行將在BeginInvoke之前的代碼執行。所以當你試圖讀取流的內容時,它已經關閉了。

兩種方式解決:

  1. finally塊取出e.ImageStream.Close();。但我不知道這個流是否會保持打開狀態。
  2. 如果1不起作用,流的內容複製到MemoryStream,然後使用該流創建WriteableBitmap

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

在這兩種情況下,不要忘了在完成創建WriteableBitmap後關閉流。