backbuffer使用您在创建WriteableBitmap时指定的像素格式,还有一个BackBufferStride属性,您可以使用它来创建一个合适的存储映射函数。

添加一些方法来设置和获取特定情况下的像素是很容易的,方法是在静态类中定义两个新的扩展方法,创建静态类只是为了承载扩展方法:

public static class bitmapextensions
{

setPixel方法首先检查x和y坐标是否在正确的范围内,格式是否为Brga32(您可以扩展该方法来处理其他格式):

public static void setPixel(this WriteableBitmap wbm, int x, int y, Color c)
{
   if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1) return;
   if (y < 0 || x < 0) return;
  if (!wbm.Format.Equals(PixelFormats.Bgra32))return;

然后它会得到backbuffer的详细信息:

   wbm.Lock();
  IntPtr buff = wbm.BackBuffer;
  int Stride = wbm.BackBufferStride;

然后计算存储映射函数来访问x、y位置的像素,并将指定的颜色分割存储为像素格式对应的4个字节:

  unsafe
  {
      byte* pbuff = (byte*)buff.ToPointer();
      int loc=y *Stride  + x*4;
      pbuff[ loc]=c.B;
      pbuff[loc+1]=c.G;
      pbuff[loc+2]=c.R;
      pbuff[loc+3]=c.A;
  }

最后我们将像素标记为dirty并解锁WriteableBitmap:

  wbm.AddDirtyRect(new Int32Rect(x,y,1,1));
  wbm.Unlock();
}

getPixel方法非常类似,只是它汇编并返回一个Color struct:

public static Color getPixel( this WriteableBitmap wbm, int x, int y)
{
  if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)  return Color.FromArgb(0, 0, 0, 0);
  if (y < 0 || x < 0) return Color.FromArgb(0, 0, 0, 0);
  if (!wbm.Format.Equals(PixelFormats.Bgra32))  return Color.FromArgb(0, 0, 0, 0);;
  IntPtr buff = wbm.BackBuffer;
  int Stride = wbm.BackBufferStride;
  Color c;
  unsafe
  {
      byte* pbuff = (byte*)buff.ToPointer();
      int loc = y * Stride + x * 4;
      c=Color.FromArgb(pbuff[loc+3],pbuff[loc+2],pbuff[loc+1],pbuff[loc]);
  }
  return c;
}

请注意,由于我们只是访问位而不更改它们,因此没有必要将某个区域锁定或标记为dirty。
这两个扩展方法很容易使用,但是如果要操作大量像素,可能需要考虑使用更直接的方法。通过Pixel属性直接访问并分配预先计算的整数颜色值总是比使用一般方法和对象要快。

定义了这些扩展方法后,我们现在可以给出一个访问像素的例子:

wbmap.setPixel(5,10 , Colors.Red);
Color c= wbmap.getPixel(5, 10);

最后,作为一个动态图像的例子,下面根据一个简单的公式,绘制了一个依赖于像素位置的颜色范围:

private void button1_Click(object sender, RoutedEventArgs e)
{
  WriteableBitmap wbmap = new WriteableBitmap(256, 256, 300, 300, PixelFormats.Bgra32, null);
  for (int x = 0; x < 256; x++)
  {
      for (int y = 0; y < 256; y++)
      {
         wbmap.setPixel( x,y,Color.FromArgb(255,(byte) (x*x+y), (byte) (y*y+x),(byte)(x+y)));
      }
  }
  image1.Source = wbmap;
}

WriteableBitmap(三) 扩展的更多相关文章

  1. 扩展KMP算法

    一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...

  2. SharePoint 2013 自定义扩展菜单

    在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...

  3. LINQ学习系列-----1.3 扩展方法

    这篇内容继续接着昨天的Lambda表达式的源码继续下去.昨天讲了Lambda表达式,此篇讲扩展方法,这两点都是Linq带来的新特性.    一.扩展方法介绍   废话不多说,先上源码截图: 上图中Ge ...

  4. 三.RabbitMQ之异步消息队列(Work Queue)

    上一篇文章简要介绍了RabbitMQ的基本知识点,并且写了一个简单的发送和接收消息的demo.这一篇文章继续介绍关于Work Queue(工作队列)方面的知识点,用于实现多个工作进程的分发式任务. 一 ...

  5. Python基础之文件处理、函数、内置函数 (三)

    内置函数 一 详细见python文档,请点击 文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 文件句柄 = file('文件路径', '模式') 注:python中打开 ...

  6. 扩展-Easyui Datagrid相同连续列合并扩展(一)

    一.autoMergeCellAndCells实现效果 调用方法: function onLoadSuccess(data){     $(this).datagrid("autoMerge ...

  7. C语言之三字棋的简单实现及扩展

    C语言之三字棋的简单实现及扩展 在我们学习完数组之后,我们完全可以利用数组相关知识来写一个微小型的游戏,比如说今天所说的--三子棋. 大纲: 文件组成 实现   完整代码展示   扩展 即: 一.文件 ...

  8. Spring的三种注入

    在学习Spring的过程中,其中一个很重要的就是依赖注入DI,在此总结一下 注入方式有三种: 一.构造器注入 二.Set方式注入(重点) 三.扩展方式注入 构造器注入: a.默认使用无参构造函数创建对 ...

  9. Jquery双向select控件Bootstrap Dual Listbox

    效果预览: 一. 下载插件 github地址:https://github.com/istvan-ujjmeszaros/bootstrap-duallistbox 也可以在这个网站中下载:http: ...

  10. [C1] C1FlexGrid 行列增删&单元格合并拆分

    上一篇中实现了 C1FlexGrid的撤销还原功能,这篇是要仿 Excel 做一个行列删除以及单元格的自由合并拆分,楼主怕在原工程里复杂的说不清道不明,所以干脆提取出来做了一个 Demo 来说明实现过 ...

随机推荐

  1. PostgreSql别名区分大小写的问题

    PostgreSql是区分大小写的,如果别名的大小不一致就会提示错误: SELECT * FROM ( SELECT cpi."product_item_id" "PRO ...

  2. Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数

    Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数~~~    呵呵... 看着有点晕.. 再解释一下就是 在Unity中 使用 C# 调用 C++ 写的 DLL, 但是在 ...

  3. java作用域public ,private ,protected 及不写时的区别

    说明部分转自:http://yangmingjiayou.iteye.com/blog/151865 在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,ba ...

  4. lua 中的点、冒号与self

    [lua 中的点.冒号与self] lua编程中,经常遇到函数的定义和调用,有时候用点号调用,有时候用冒号调用. girl = {money = 200} function girl.goToMark ...

  5. php71 gdnz

    更新yum库:yum updat yum install epel-release yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel ...

  6. 删除Eclipse已有的SVN资源库位置

    点击Eclipse菜单栏的[Window]->[Show View]->[Other],在弹出的对话框中,选择[SVN]->[SVN资源库],然后点击[OK]. 接着,在Eclips ...

  7. 7.Reverse Integer (INT; Overflow)

    Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 思路:要注意溢出 ...

  8. awk:好用的数据处理工具

    awk 也是一个非常棒的数据处理工具!sed 常常用于一整个行的处理, awk 则比较倾向于一行当中分成数个『栏位』(或者称为一个域,也就是一列)来处理.因此,awk 相当的适合处理小型的数据数据处理 ...

  9. redhat安装xwindow环境

    . yum groupinstall "X Window System" . yum groupinstall "GNOME Desktop Environment&qu ...

  10. Ubuntu的人性化配置

    1.更改Ubuntu命令行提示符颜色,在~/.bashrc中添加如下命令行: PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[ ...