2012年4月24日 星期二

在 WriteableBitmap 上繪製 Image

最近需要利用程式流程產生合適的圖片並儲存成 jpg 檔案…
平常寫 C++/MFC 其實有很大部份時間都是在做畫圖這種事…
用 C#/WPF or Silverlight 還是頭一次…方法大不同…蠻新鮮的體驗…

這次的需求是要在 Windows Phone 上產生圖片…
憑著以前的經驗大概知道是要用 WriteableBitmap 來做…
看了一下文件也了解要用 Render、Invalidate 來做…卻一開始就碰壁…
後來才知道很幸運的…我第一個要畫上去的東西就是唯一有問題的元件 XD

最初我寫的程式碼大概就像這樣…但沒有作用…

WriteableBitmap mBitmap = new WriteableBitmap();

Image img = new Image();
img.Width = 18;
img.Height = 16;
BitmapImage bmp = new BitmapImage(new Uri("sample.png", UriKind.Relative));
img.Source = bmp;
mBitmap.Render(img, null);

找了一下資料有些人說 Image、BitmapImage 的讀取是 Async 的…
所以在指定完 Source 立刻 Render 很有可能會畫成空的 Image…
改成這些人建議的方式如下…其實也沒作用…
而且 ImageOpened 有時會觸發有時不會…看來也幫不上忙…

mImg = new Image()
{
    Width = 18,
    Height = 16,
    Source = new BitmapImage(new Uri("sample.png", UriKind.Relative)),
};
mImg.ImageOpened += OnRainImageOpened;


private void OnRainImageOpened(object sender, RoutedEventArgs e)
{
    mBitmap.Render(mImg, null);
    mBitmap.Invalidate();
}

最後改用 StreamResource 的方式成功的把 Image 畫上去了…
但是原因如何我還真的不太清楚…猜測應該是避開了 Async 的問題吧…
總之可以正確將 Image 畫在 WriteableBitmap 的程式碼如下…

StreamResourceInfo resource = Application.GetResourceStream(new Uri("sample.png", UriKind.Relative));
BitmapImage bmp;
using (resource.Stream)
{
    bmp = new BitmapImage();
    bmp.SetSource(resource.Stream);
    resource.Stream.Close();
}
Image img = new Image()
{
    Width = 18,
    Height = 16,
    Source = bmp,
};
mBitmap.Render(img, null);

沒有留言:

張貼留言