【WPF】WriteableBitmap应用及图片数据格式转换

使用 WriteableBitmap 类基于每个框架来更新和呈现位图。这对于生成算法内容(如分形图像)和数据可视化(如音乐可视化工具)很有用。

WriteableBitmap 类使用两个缓冲区。“后台缓冲区”在系统内存中分配,它可以累计当前未显示的内容。“前台缓冲区”在系统内存中分配,它包含当前显示的内容。呈现系统将前台缓冲区复制到视频内存中以便显示。

两个线程使用这两个缓冲区。“用户界面 (UI) 线程”生成 UI 但不将其呈现在屏幕上。UI 线程响应用户输入、计时器以及其他事件。一个应用程序可以具有多个 UI 线程。“呈现线程”撰写和呈现 UI 线程的变化。每个应用程序只有一个呈现线程。

UI 线程将内容写入后台缓冲区。呈现线程从前台缓冲区读取内容,然后将其复制到视频内存中。将使用更改的矩形区域跟踪对后台缓冲区的更改。

WriteableBitmap使用两个线程来使用这两个缓冲区。UI 线程响应用户输入、计时器以及其他事件。“呈现线程”撰写和呈现 UI 线程的变化。在WriteableBitmap中,UI 线程将内容写入后台缓冲区。呈现线程从前台缓冲区读取内容,然后将其复制到视频内存中,最后切换两个缓存区。

WritePixel方法

可以使用WritePixel方法来更新缓冲区:

1. public void WritePixels(Int32Rect sourceRect, Array pixels, int stride, int offset);
2. public void WritePixels(Int32Rect sourceRect, IntPtr buffer, int bufferSize, int stride);
3. public void WritePixels(Int32Rect sourceRect, Array sourceBuffer, int sourceBufferStride,
      int destinationX, int destinationY);
4. public void WritePixels(Int32Rect sourceRect, IntPtr sourceBuffer, int sourceBufferSize,
      int sourceBufferStride, int destinationX, int destinationY);

关于Stride

Stride是Bitmap里一个令人头痛的东西,它代表着一张图片每一行的扫描宽度(跨距)。跨距总是大于或等于实际像素宽度。如果跨距为正,则位图自顶向下。如果跨距为负,则位图颠倒。Stride是指图像每一行需要占用的字节数。根据BMP格式的标准,Stride一定要是4的倍数。据个例子,一幅1024*768的24bppRgb的图像,每行有效的像素信息应该是1024*3 = 3072。因为已经是4的倍数,所以Stride就是3072。那么如果这幅图像是35*30,那么一行的有效像素信息是105,但是105不是4的倍数,所以填充空字节(也就是0),Stride应该是108。

在WritableBitmap中,可以使用:

.BackBufferStride 

属性来获得Stride值。

明白了Stride的意义,让我们来看看以下代码:

WriteableBitmap bitmap = new WriteableBitmap(15, 2, 72, 72, PixelFormats.Bgr24, null);
Byte[] buffer = new Byte[bitmap.BackBufferStride * bitmap.PixelHeight];
for (byte i = 0; i < buffer.Length; i++)
{
    buffer[i] = i;
}
bitmap.WritePixels(new Int32Rect(0, 0, 15, 2), buffer, bitmap.BackBufferStride, 0);

Marshal.Copy(bitmap.BackBuffer, buffer, 0, buffer.Length);

在上面的代码里,我们新建了一个15X2的24位位图,它的行跨距是(15*3+3)/4*4=48,没行多了3个填充字节。我们把一个由0到95的连续数组复制到该位图中,然后重新复制回来,可以看到,第45、46、47个元素值是0:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值