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. servlet类第二篇

    1servlet的生命周期是什么? 服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始 ...

  2. scala 基本语法

    1.对于一个二元数组,键值对(k,v) 用map的时候,要取第一个或者第二个元素,用 _1 或者 _2表示. scala> words.take(2)res40: Array[(String, ...

  3. 贝叶斯vs频率派:武功到底哪家强?| 说人话的统计学·协和八(转)

    回我们初次见识了统计学理论中的“独孤九剑”——贝叶斯统计学(戳这里回顾),它的起源便是大名鼎鼎的贝叶斯定理. 整个贝叶斯统计学的精髓可以用贝叶斯定理这一条式子来概括: 我们做数据分析,绝大多数情况下希 ...

  4. ensembl数据库的使用方法

    1)下载各种数据bam.gtf.fasta.ded等的地址 ftp://ftp.ensembl.org/../pub/release-93/

  5. Ubuntu 18.04上安装R及Rstudio

    安装R引用自:https://www.howtoing.com/how-to-install-r-on-ubuntu-18-04 安装Rstudio引用自:https://www.rstudio.co ...

  6. Python3 ord() 函数

    Python3 ord() 函数  Python3 内置函数 描述 ord() 函数是 chr() 函数(对于 8 位的 ASCII 字符串)的配对函数,它以一个字符串(Unicode 字符)作为参数 ...

  7. 使用css实现特殊标志或图形

    1. 前言 由于图片占的空间比较大,且图片越多,越不好管理,所以有些时候,我们可以使用一些简单的标签样式来实现简单的图形标志来替代图片. 2. 实例展示: 三角形示例 示例代码: <style ...

  8. python之多线程队列

    # 一共有以下3种队列# 1.先进先出# 2.后进先出# 3.存储数据的时候可设置优先级的队列,设置不同的优先级,取的时候按照优先级的顺序来取 下面介绍一下队列的方法,如果要使用队列,则需要导入一个模 ...

  9. [leetcode]124. Binary Tree Maximum Path Sum二叉树最大路径和

    Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...

  10. google中guava类库:AsyncEventBus

    1.guava事件总线(AsyncEventBus)使用 1.1引入依赖 <dependency> <groupId>com.google.guava</groupId& ...