2012年1月11日 星期三

WPF的BitmapImage佔用資源的處理方式

我們經常使用Image控制項來載入圖片,簡單的作法,直接在IDE開發環境中,在Image的屬性頁面設定Source屬性即可。但,我們有時候會需要將圖檔動態的讀入,怎麼寫?可想到程式碼如下:

  // 開檔

  String FilePath = @"C:\temp\001 (1).jpg";
  FileStream FStream = new FileStream( FilePath, FileMode.Open );


  // 將資料讀入 BitmapImage 變成圖檔資源
  BitmapImage BitMap = new BitmapImage( );
  BitMap.BeginInit( );
  BitMap.StreamSource = FStream ;
  BitMap.EndInit( );


  // 放到 Image 元件中,顯示圖片
  ImageControl.BeginInit( );
  ImageControl.Source = BitMap;
  ImageControl.EndInit( );
   // FStream.Close( );     不可Close,不然圖片不會出來





可是這樣會遇到一個問題,載入圖檔之後,原本的圖檔會無法刪除,或被別人使用,因為資源被Stream鎖住了,如果你在程式中把FStream給Close了,那麼,執行的時候就看不到圖了(什麼機制嘛!)所以要改成底下的作法,把檔案讀到記憶體裡面


  // 開檔
  String FilePath = @"C:\temp\001 (1).jpg";
  FileStream FStream = new FileStream( FilePath, FileMode.Open );


  // 轉成 Binary
  BinaryReader BinReader = new BinaryReader( FStream );
  byte[] BinaBytes = BinReader.ReadBytes( (int)FStream.Length );


  // 資料變成 MemoryStream (如此檔案就跟此程式無關連了,可關閉、刪除)
  MemoryStream MStream = new MemoryStream( BinaBytes );
  BinReader.Close( );
  FStream.Close( );


  // 將資料讀入 BitmapImage 變成圖檔資源
  BitmapImage BitMap = new BitmapImage( );
  BitMap.BeginInit( );
  BitMap.StreamSource = MStream ;
  BitMap.EndInit( );


  // 放到 Image 元件中,顯示圖片
  ImageControl.BeginInit( );
  ImageControl.Source = BitMap;
  ImageControl.EndInit( );
  //MStream.Close( );     不可Close,不然圖片不會出來








這樣,檔案可以更動了(因為FileStream關閉啦),可是,MemoryStream一樣無法關閉,不然圖片不會出來,這樣還是沒有解決問題,根本的作法,是預先載入,設定BitmapCacheOption,這樣,就可以回到第一個作法,簡單作出來。



  // 開檔
  String FilePath = @"C:\temp\001 (1).jpg";
  FileStream FStream = new FileStream( FilePath, FileMode.Open );


  // 將資料讀入 BitmapImage 變成圖檔資源
  BitmapImage BitMap = new BitmapImage( );
  BitMap.BeginInit( );
  BitMap.StreamSource = FStream ;
  BitMap .CacheOption =  BitmapCacheOption.OnLoad;
  BitMap.EndInit( );
  FStream.Close();  



  // 放到 Image 元件中,顯示圖片
  ImageControl.BeginInit( );
  ImageControl.Source = BitMap;
  ImageControl.EndInit( );


1 則留言: