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. mysql改数据库名称

    第一种方法: 1.创建需要改成新名的数据库.2.mysqldum 导出要改名的数据库3.删除原来的旧库(确定是否真的需要)当然这种方法虽然安全,但是如果数据量大,会比较耗时,哎,当时连这种方法都没有想 ...

  2. TPCC-MySQL的安装与使用

    Tpcc-mysql 是 percona 基于 tpcc 衍生出来的产品,专用于 mysql 基准测试,其源码放在 bazaar 上( Bazaar 是一个分布式的版本控制系统,采用 GPL 许可协议 ...

  3. tair介绍以及配置

    简介 tair 是淘宝自己开发的一个分布式 key/value 存储引擎. tair 分为持久化和非持久化两种使用方式. 非持久化的 tair 可以看成是一个分布式缓存. 持久化的 tair 将数据存 ...

  4. memcache命令

    Command Description Example get 读取键值 get mykey set 设置新键值 set mykey 0 60 5 add 新增键值 add newkey 0 60 5 ...

  5. Delphi中拖动的方式来移动TPageControl的Tab

    procedure TMainForm.PageControl1MouseDown(Sender: TObject;   Button: TMouseButton; Shift: TShiftStat ...

  6. servlet第三篇

    Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度. 针对客户端的多次Servlet请求,通常情况下,服务器只会 ...

  7. express + mongodb 搭建一个简易网站(一)

    express + mongodb 搭建一个简易网站(一) 前言:后台使用node.js的express框架,数据库使用mongodb,模板使用ejs.大概就这些. 开始第一个简易网站之旅吧.... ...

  8. 《Blue Flke》第一次作业:团队亮相

    1.队名:Blue Flke 团队格言:决心是成功的力量,耐心是成功的保障. 2.团队成员组成:  201571030129/ 王胜海 (组长)  201571030126/ 妥志福 20157103 ...

  9. Java ReentrantLock和synchronized两种锁定机制的对比

    多线程和并发性并不是什么新内容,但是 Java 语言设计中的创新之一就是,它是第一个直接把跨平台线程模型和正规的内存模型集成到语言中的主流语言.核心类库包含一个 Thread 类,可以用它来构建.启动 ...

  10. Jakarta项目

    Jakarta项目是ASF(The Apache Software Foundation)的一部分.ASF是一个非赢利组织,她鼓励基于开放的软件许可下进行合作.注重实效的开发,并提供各个领域的高质量软 ...