在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel,

如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操作完在复制回去可以加快访问速度

其实对Bitmap的访问还有两种方式,一种是内存法,一种是指针法

1、内存法

  这里定义一个类LockBitmap,通过把Bitmap数据拷贝出来,在内存上直接操作,操作完成后在拷贝到Bitmap中

public class LockBitmap
{
Bitmap source = null;
IntPtr Iptr = IntPtr.Zero;
BitmapData bitmapData = null; public byte[] Pixels { get; set; }
public int Depth { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; } public LockBitmap(Bitmap source)
{
this.source = source;
} /// <summary>
/// Lock bitmap data
/// </summary>
public void LockBits()
{
try
{
// Get width and height of bitmap
Width = source.Width;
Height = source.Height; // get total locked pixels count
int PixelCount = Width * Height; // Create rectangle to lock
Rectangle rect = new Rectangle(, , Width, Height); // get source bitmap pixel format size
Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat); // Check if bpp (Bits Per Pixel) is 8, 24, or 32
if (Depth != && Depth != && Depth != )
{
throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
} // Lock bitmap and return bitmap data
bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
source.PixelFormat); // create byte array to copy pixel values
int step = Depth / ;
Pixels = new byte[PixelCount * step];
Iptr = bitmapData.Scan0; // Copy data from pointer to array
Marshal.Copy(Iptr, Pixels, , Pixels.Length);
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// Unlock bitmap data
/// </summary>
public void UnlockBits()
{
try
{
// Copy data from byte array to pointer
Marshal.Copy(Pixels, , Iptr, Pixels.Length); // Unlock bitmap data
source.UnlockBits(bitmapData);
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// Get the color of the specified pixel
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Color GetPixel(int x, int y)
{
Color clr = Color.Empty; // Get color components count
int cCount = Depth / ; // Get start index of the specified pixel
int i = ((y * Width) + x) * cCount; if (i > Pixels.Length - cCount)
throw new IndexOutOfRangeException(); if (Depth == ) // For 32 bpp get Red, Green, Blue and Alpha
{
byte b = Pixels[i];
byte g = Pixels[i + ];
byte r = Pixels[i + ];
byte a = Pixels[i + ]; // a
clr = Color.FromArgb(a, r, g, b);
}
if (Depth == ) // For 24 bpp get Red, Green and Blue
{
byte b = Pixels[i];
byte g = Pixels[i + ];
byte r = Pixels[i + ];
clr = Color.FromArgb(r, g, b);
}
if (Depth == )
// For 8 bpp get color value (Red, Green and Blue values are the same)
{
byte c = Pixels[i];
clr = Color.FromArgb(c, c, c);
}
return clr;
} /// <summary>
/// Set the color of the specified pixel
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="color"></param>
public void SetPixel(int x, int y, Color color)
{
// Get color components count
int cCount = Depth / ; // Get start index of the specified pixel
int i = ((y * Width) + x) * cCount; if (Depth == ) // For 32 bpp set Red, Green, Blue and Alpha
{
Pixels[i] = color.B;
Pixels[i + ] = color.G;
Pixels[i + ] = color.R;
Pixels[i + ] = color.A;
}
if (Depth == ) // For 24 bpp set Red, Green and Blue
{
Pixels[i] = color.B;
Pixels[i + ] = color.G;
Pixels[i + ] = color.R;
}
if (Depth == )
// For 8 bpp set color value (Red, Green and Blue values are the same)
{
Pixels[i] = color.B;
}
}
}

使用:先锁定Bitmap,然后通过Pixels操作颜色对象,最后释放锁,把数据更新到Bitmap中

string file = @"C:\test.jpg";
Bitmap bmp = new Bitmap(Image.FromFile(file)); LockBitmap lockbmp = new LockBitmap(bmp);
//锁定Bitmap,通过Pixel访问颜色
lockbmp.LockBits(); //获取颜色
Color color = lockbmp.GetPixel(, ); //从内存解锁Bitmap
lockbmp.UnlockBits();

2、指针法

  这种方法访问速度比内存法更快,直接通过指针对内存进行操作,不需要进行拷贝,但是在C#中直接通过指针操作内存是不安全的,所以需要在代码中加入unsafe关键字,在生成选项中把允许不安全代码勾上,才能编译通过

  这里定义成PointerBitmap类

public class PointBitmap
{
Bitmap source = null;
IntPtr Iptr = IntPtr.Zero;
BitmapData bitmapData = null; public int Depth { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; } public PointBitmap(Bitmap source)
{
this.source = source;
} public void LockBits()
{
try
{
// Get width and height of bitmap
Width = source.Width;
Height = source.Height; // get total locked pixels count
int PixelCount = Width * Height; // Create rectangle to lock
Rectangle rect = new Rectangle(, , Width, Height); // get source bitmap pixel format size
Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat); // Check if bpp (Bits Per Pixel) is 8, 24, or 32
if (Depth != && Depth != && Depth != )
{
throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
} // Lock bitmap and return bitmap data
bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
source.PixelFormat); //得到首地址
unsafe
{
Iptr = bitmapData.Scan0;
//二维图像循环 }
}
catch (Exception ex)
{
throw ex;
}
} public void UnlockBits()
{
try
{
source.UnlockBits(bitmapData);
}
catch (Exception ex)
{
throw ex;
}
} public Color GetPixel(int x, int y)
{
unsafe
{
byte* ptr = (byte*)Iptr;
ptr = ptr + bitmapData.Stride * y;
ptr += Depth * x / ;
Color c = Color.Empty;
if (Depth == )
{
int a = ptr[];
int r = ptr[];
int g = ptr[];
int b = ptr[];
c = Color.FromArgb(a, r, g, b);
}
else if (Depth == )
{
int r = ptr[];
int g = ptr[];
int b = ptr[];
c = Color.FromArgb(r, g, b);
}
else if (Depth == )
{
int r = ptr[];
c = Color.FromArgb(r, r, r);
}
return c;
}
} public void SetPixel(int x, int y, Color c)
{
unsafe
{
byte* ptr = (byte*)Iptr;
ptr = ptr + bitmapData.Stride * y;
ptr += Depth * x / ;
if (Depth == )
{
ptr[] = c.A;
ptr[] = c.R;
ptr[] = c.G;
ptr[] = c.B;
}
else if (Depth == )
{
ptr[] = c.R;
ptr[] = c.G;
ptr[] = c.B;
}
else if (Depth == )
{
ptr[] = c.R;
ptr[] = c.G;
ptr[] = c.B;
}
}
}
}

使用方法这里就不列出来了,跟上面的LockBitmap类似

以上图片由“图斗罗”提供

C#加快Bitmap的访问速度的更多相关文章

  1. 加快Bitmap的访问速度

    引言 在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel, 如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操 ...

  2. .net 反射访问私有变量和私有方法 如何创建C# Closure ? C# 批量生成随机密码,必须包含数字和字母,并用加密算法加密 C#中的foreach和yield 数组为什么可以使用linq查询 C#中的 具名参数 和 可选参数 显示实现接口 异步CTP(Async CTP)为什么那样工作? C#多线程基础,适合新手了解 C#加快Bitmap的访问速度 C#实现对图片文件的压

    以下为本次实践代码: using System; using System.Collections.Generic; using System.ComponentModel; using System ...

  3. Apache 使用gzip、deflate 压缩页面加快网站访问速度

    Apache 使用gzip 压缩页面加快网站访问速度 介绍: 网页压缩来进一步提升网页的浏览速度,它完全不需要任何的成本,只不过是会让您的服务器CPU占用率稍微提升一两个百分点而已或者更少.   原理 ...

  4. [技术博客]使用CDN加快网站访问速度

    [技术博客]使用CDN加快网站访问速度 2s : most users are willing to wait 10s : the limit for keeping the user's atten ...

  5. 2-12-配置squid代理服务器加快网站访问速度

    本节所讲内容: squid服务器常见概念 squid服务器安装及相关配置文件 实战:配置squid正向代理服务器 实战:配置透明squid代理提升访问速度 实战:配置squid反向代理加速度内网web ...

  6. maven中央仓库访问速度太慢的解决办法

    方法一:修改settings.xml eclipse中集成的maven的settings.xml文件,找了半年也没找到,我们放弃eclipse中的maven,下一个最新的maven,并在eclipse ...

  7. Nginx——使用 Nginx 提升网站访问速度【转载+整理】

    原文地址 本文是写于 2008 年,文中提到 Nginx 不支持 Windows 操作系统,但是现在它已经支持了,此外还支持 FreeBSD,Solaris,MacOS X~ Nginx(" ...

  8. 使用 Nginx 提升网站访问速度

    使用 Nginx 提升网站访问速度 http://www.ibm.com/developerworks/cn/web/wa-lo-nginx/ Nginx 简介 Nginx ("engine ...

  9. 使用PHP和GZip压缩网站JS/CSS文件加速网站访问速度

    使用PHP和GZip压缩网站JS/CSS文件加速网站访问速度 一些泛WEB 2.0网站为了追求用户体验,可能会大量使用CSS和JS文件.这就导致在服务器带宽一定的情况下,多用户并发访问速度变慢.如何加 ...

随机推荐

  1. position与float属性的使用

    1.使用float时,可以说是用于布局,取值主要有left.right.none.就是将该块的元素浮动起来,在浏览器默认的情况下,该元素的位置是为空的, 即脱离了文档流而存在,如果有其他元素,那么这些 ...

  2. cf #363 d

      time limit per test 2 seconds memory limit per test 256 megabytes input standard input output stan ...

  3. 关于ZBarReaderView 打开闪光灯

    关于ZBarReaderView 打开闪光灯 ZBarReaderView *readerView; - (void)changeLight:(id)sender{ UIButton *btn = ( ...

  4. 计算 24 点是一种扑克牌益智游戏,随机抽出 4 张扑克牌,通过加 (+) ,减 (-) ,乘 ( * ), 除 (/) 四种运算法则计算得到整数 24 ,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写 joker 表示小王,大写 JOKER 表示大王:

    include "stdafx.h" #include <iostream> #include <fstream> #include <string& ...

  5. 我的 Android 开发实战经验总结

    我的 Android 开发实战经验总结 字数4440 阅读5137 评论43 喜欢250 曾经一直想写一篇总结 Android 开发经验的文章,预计当时的我还达不到某种水平,所以思路跟不上,下笔又捉襟 ...

  6. Blue Jeans - poj 3080(后缀数组)

    大致题意: 给出n个长度为60的DNA基因(A腺嘌呤 G鸟嘌呤 T胸腺嘧啶 C胞嘧啶)序列,求出他们的最长公共子序列 使用后缀数组解决 #include<stdio.h> #include ...

  7. ThinkPHP与EasyUI整合之二(datagrid):删除多条记录

    学习EasyUI已有一段时间了,现在开始逐步把平时学习的细节和难点记录下来. 1. datagrid选中多条记录的语句是: var rows = $('#dg').datagrid('getSelec ...

  8. 第一百八十四节,jQuery-UI,验证注册表单

    jQuery-UI,验证注册表单 html <form id="reg" action="123.html" title="会员注册" ...

  9. 理解和使用WPF 验证机制(值得推荐)

    首先建立一个demo用以学习和实验WPF Data Validation机制.创建一个数据实体类: public class Employee { public string Name { get;  ...

  10. (转)Resources和AssetBundle(新旧版)学习

    Resources:   Resources的缺点:1.与显示Inspector上直接引用相比,Resources使用不方便.     2.不管你Resources上的资源是否调用了,当你发布的时候, ...