WPF_WriteableBitmap类

WPF_WriteableBitmap类

一、前言

在WPF中允许使用Image元素显示位图。可直接设置Image的Source属性(是一个ImageSource类型),则可直接显示位图。

<Image x:Name="myImage" Source="Resources/A.jpg" Stretch="Fill" />
myimage.Source = new BitmapImage(new Uri(@"./Resource/A.jpg", UriKind.Relative));

需要将图片添加到项目的资源中,并在属性中将生成操作改为Resource。

Image元素没有提供创建或者编辑位图信息的方法。

这正是WriteableBitmap类的用武之地。该类继承自BitmapSource,BitmapSource类继承自ImageSource。Image的Source属性是ImageSource类型,但BitmapSource是只读的位图数据映射。

Image +ImageSource Source ImageSource BitmapSource WriteableBitmap BitmapImage

二、生成位图

为使用WriteableBitmap类生成一副位图,需要以像素为单位的宽度、以像素为单位的高度、两个方向的DPI分辨率以及图形格式。

WriteableBitmap Wb = new WriteableBitmap(640, 480, 96, 96, PixelFormats.Bgra32, null);

最后一个参数当PixelFormat=PixelFormats.Indexed时才需要,这里不举例了。

三、写入WriteableBitmap对象

开始时,WriteableBitmap对象中所有字节的值都是0.本质上,就是一个大的黑色矩形。为使用内容填充WriteableBitmap对象,需要使用WritePixels()方法。

//因为像素格式是32位的,所以这里直接定义为UInt32类型表示一个像素的大小。
            //因为转成四字节的顺序必须为blue green red alpha。所以在UInt32数据中blue放在低位
            UInt32[] pixels = new UInt32[Wb.PixelWidth * Wb.PixelHeight];
            Random random = new Random();
            for (int y = 0; y < Wb.PixelHeight; y++)
            {
                for (int x = 0; x < Wb.PixelWidth; x++)
                {
                    int offset = y * Wb.PixelWidth + x;

                    byte blue = (byte)random.Next(0, 255);
                    byte green = (byte)random.Next(0, 255);
                    byte red = (byte)random.Next(0, 255);
                    byte alpha = 255;

                    if ((y + 1) % 10 == 0 || (x + 1) % 10 == 0)
                        alpha = 0;
                    byte[] pixel = new byte[4] { blue, green, red, alpha };

                    pixels[offset] = BitConverter.ToUInt32(pixel, 0);
                }
            }
            int stride = Wb.PixelWidth * (Wb.Format.BitsPerPixel / 8);

            Wb.WritePixels(new Int32Rect(0, 0, Wb.PixelWidth, Wb.PixelHeight), pixels, stride, 0);

值得一提的是stride(跨距)的计算,跨距是每行像素数据需要的字节数量。

在实际应用程序中,可选择折中方法。如果需要更新位图中一块较大的区域,不会一次写入一个像素,因为折中方法运行速度太慢。如果图像数据很大,也不会在内存中同时保存全部数据数据然后一次性写入。
在这里插入图片描述

四、频繁更新图像数据

需要使用WriteableBitmap后台缓冲区,详见:WriteableBitmap 类 (System.Windows.Media.Imaging) | Microsoft Docs

五、示例

1、随机初始化了一个WriteableBitmap对象,装载再Image元素上
2、对于Image元素,可以使用鼠标滑轮进行缩放,使用按键W、S、A和D进行平移
3、鼠标左键按住移动的时候,对应位置会被重新填充为黑色(实际不止那一个像素)
4、鼠标右键则会重新初始化WriteableBitmap对象
源代码点我
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值