WriteableBitmap 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供一個可以寫入並更新的檔案 BitmapSource 。
public ref class WriteableBitmap sealed : System::Windows::Media::Imaging::BitmapSource
public sealed class WriteableBitmap : System.Windows.Media.Imaging.BitmapSource
type WriteableBitmap = class
inherit BitmapSource
Public NotInheritable Class WriteableBitmap
Inherits BitmapSource
- 繼承
-
WriteableBitmap
範例
以下範例展示了如何使用 a WriteableBitmap 作為 的來源 Image ,在滑鼠移動時繪製像素。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Input;
namespace WriteableBitmapDemo
{
class Program
{
static WriteableBitmap writeableBitmap;
static Window w;
static Image i;
[STAThread]
static void Main(string[] args)
{
i = new Image();
RenderOptions.SetBitmapScalingMode(i, BitmapScalingMode.NearestNeighbor);
RenderOptions.SetEdgeMode(i, EdgeMode.Aliased);
w = new Window();
w.Content = i;
w.Show();
writeableBitmap = new WriteableBitmap(
(int)w.ActualWidth,
(int)w.ActualHeight,
96,
96,
PixelFormats.Bgr32,
null);
i.Source = writeableBitmap;
i.Stretch = Stretch.None;
i.HorizontalAlignment = HorizontalAlignment.Left;
i.VerticalAlignment = VerticalAlignment.Top;
i.MouseMove += new MouseEventHandler(i_MouseMove);
i.MouseLeftButtonDown +=
new MouseButtonEventHandler(i_MouseLeftButtonDown);
i.MouseRightButtonDown +=
new MouseButtonEventHandler(i_MouseRightButtonDown);
w.MouseWheel += new MouseWheelEventHandler(w_MouseWheel);
Application app = new Application();
app.Run();
}
// The DrawPixel method updates the WriteableBitmap by using
// unsafe code to write a pixel into the back buffer.
static void DrawPixel(MouseEventArgs e)
{
int column = (int)e.GetPosition(i).X;
int row = (int)e.GetPosition(i).Y;
try{
// Reserve the back buffer for updates.
writeableBitmap.Lock();
unsafe
{
// Get a pointer to the back buffer.
IntPtr pBackBuffer = writeableBitmap.BackBuffer;
// Find the address of the pixel to draw.
pBackBuffer += row * writeableBitmap.BackBufferStride;
pBackBuffer += column * 4;
// Compute the pixel's color.
int color_data = 255 << 16; // R
color_data |= 128 << 8; // G
color_data |= 255 << 0; // B
// Assign the color data to the pixel.
*((int*) pBackBuffer) = color_data;
}
// Specify the area of the bitmap that changed.
writeableBitmap.AddDirtyRect(new Int32Rect(column, row, 1, 1));
}
finally{
// Release the back buffer and make it available for display.
writeableBitmap.Unlock();
}
}
static void ErasePixel(MouseEventArgs e)
{
byte[] ColorData = { 0, 0, 0, 0 }; // B G R
Int32Rect rect = new Int32Rect(
(int)(e.GetPosition(i).X),
(int)(e.GetPosition(i).Y),
1,
1);
writeableBitmap.WritePixels( rect, ColorData, 4, 0);
}
static void i_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
ErasePixel(e);
}
static void i_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DrawPixel(e);
}
static void i_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DrawPixel(e);
}
else if (e.RightButton == MouseButtonState.Pressed)
{
ErasePixel(e);
}
}
static void w_MouseWheel(object sender, MouseWheelEventArgs e)
{
System.Windows.Media.Matrix m = i.RenderTransform.Value;
if (e.Delta > 0)
{
m.ScaleAt(
1.5,
1.5,
e.GetPosition(w).X,
e.GetPosition(w).Y);
}
else
{
m.ScaleAt(
1.0 / 1.5,
1.0 / 1.5,
e.GetPosition(w).X,
e.GetPosition(w).Y);
}
i.RenderTransform = new MatrixTransform(m);
}
}
}
備註
使用這個 WriteableBitmap 類別來更新並渲染每幀的位圖。 這對於產生演算法內容(如分形影像)以及資料視覺化(如音樂視覺化器)非常有用。
這個 WriteableBitmap 類別使用兩個緩衝區。 後備緩衝區被分配在系統記憶體中,並累積目前未顯示的內容。 前置緩衝區分配於系統記憶體中,包含目前顯示的內容。 渲染系統會將前方緩衝區複製到視訊記憶體以供顯示。
兩個執行緒使用這些緩衝區。 使用者介面(UI)執行緒會產生使用者介面,但不會將其呈現到螢幕上。 UI 執行緒會回應使用者輸入、計時器及其他事件。 一個應用程式可以有多個 UI 執行緒。 渲染執行緒會從 UI 執行緒中組合並渲染變更。 每個應用程式只有一個渲染執行緒。
UI 執行緒會將內容寫入後置緩衝區。 渲染執行緒會從前方緩衝區讀取內容並複製到視訊記憶體。 後方緩衝區的變化會以變更的矩形區域來追蹤。
呼叫其中一個超載程式 WritePixels ,自動更新並顯示後方緩衝區的內容。
為了更好地控制更新,並實現多執行緒存取後方緩衝區,請使用以下工作流程。
呼叫 Lock 該方法來保留後備緩衝區以供更新。
透過存取 BackBuffer 該屬性取得指向後方緩衝區的指標。
將變更寫入後方緩衝區。 其他執行緒可能會在後 WriteableBitmap 方緩衝區被鎖定時寫入變更。
請致電該 AddDirtyRect 方法以標示已改變的區域。
呼叫 Unlock 方法釋放後方緩衝區,並允許螢幕呈現。
當更新傳送到渲染執行緒時,渲染執行緒會將修改後的矩形從後緩衝區複製到前緩衝區。 渲染系統會控制這種交換,以避免死結並重繪偽影,例如「撕裂」。
建構函式
| 名稱 | Description |
|---|---|
| WriteableBitmap(BitmapSource) |
使用給定BitmapSource的 初始化類別的新實例WriteableBitmap。 |
| WriteableBitmap(Int32, Int32, Double, Double, PixelFormat, BitmapPalette) |
初始化一個新的類別實例 WriteableBitmap ,並以指定參數進行。 |
屬性
| 名稱 | Description |
|---|---|
| BackBuffer |
會拿到指向後方緩衝區的指標。 |
| BackBufferStride |
會得到一個表示單一像素資料列中位元組數的值。 |
| CanFreeze |
會得到一個值,表示該物件是否能被設定為不可修改。 (繼承來源 Freezable) |
| DependencyObjectType |
會取得 DependencyObjectType 包裹此實例 CLR 類型的 。 (繼承來源 DependencyObject) |
| Dispatcher |
了解 Dispatcher 這與此 DispatcherObject 有關。 (繼承來源 DispatcherObject) |
| DpiX |
取得圖片的水平點數每英吋(dpi)。 (繼承來源 BitmapSource) |
| DpiY |
取得影像垂直點數每英吋(dpi)。 (繼承來源 BitmapSource) |
| Format |
取得點陣圖資料的原生 PixelFormat 版本。 (繼承來源 BitmapSource) |
| HasAnimatedProperties |
會得到一個值,表示是否有一個或多個 AnimationClock 物件與該物件的相依屬性相關聯。 (繼承來源 Animatable) |
| Height |
取得來源位圖高度,單位與裝置無關(每單位 1/96 英吋)。 (繼承來源 BitmapSource) |
| IsDownloading |
會得到一個值,表示內容是否 BitmapSource 正在下載中。 (繼承來源 BitmapSource) |
| IsFrozen |
會得到一個值,表示該物件目前是否可修改。 (繼承來源 Freezable) |
| IsSealed |
會獲得一個值,表示該實例目前是否封存(唯讀)。 (繼承來源 DependencyObject) |
| Metadata |
取得與此點陣圖影像相關的元資料。 (繼承來源 BitmapSource) |
| Palette |
如果有指定,會取得點陣圖的色彩調色盤。 (繼承來源 BitmapSource) |
| PixelHeight |
它會取得點陣圖的高度(像素單位)。 (繼承來源 BitmapSource) |
| PixelWidth |
會得到點陣圖的寬度(像素數)。 (繼承來源 BitmapSource) |
| Width |
以裝置獨立單位取得位圖寬度(每單位 1/96 英吋)。 (繼承來源 BitmapSource) |
方法
事件
| 名稱 | Description |
|---|---|
| Changed |
當 Freezable 它所包含的物件被修改時,會發生這種情況。 (繼承來源 Freezable) |
| DecodeFailed |
當影像檔因檔案標頭損毀而無法載入時,會發生這種情況。 (繼承來源 BitmapSource) |
| DownloadCompleted |
當點陣圖內容已經完全下載完畢時,會發生這種情況。 (繼承來源 BitmapSource) |
| DownloadFailed |
當點陣圖內容下載失敗時會發生。 (繼承來源 BitmapSource) |
| DownloadProgress |
當點陣圖內容的下載進度改變時,會發生這種情況。 (繼承來源 BitmapSource) |
明確介面實作
| 名稱 | Description |
|---|---|
| IFormattable.ToString(String, IFormatProvider) |
使用指定的格式,格式化目前實例的值。 (繼承來源 ImageSource) |