zoukankan      html  css  js  c++  java
  • 类库探源——System.Drawing.Bitmap

    一、System.Drawing.Bitmap

    Bitmap 类: 封装GDI+ 位图,此位图由图形图像及其属性的像素数据组成。Bitmap 是用于处理由像素定义的图像的对象

    命名空间: System.Drawing

    程序集:   System.Drawing.dll

    继承关系:

    原型定义:

    [SerializableAttribute]
    [ComVisibleAttribute(true)]
    public sealed class Bitmap : Image

    备注:
    GDI+ 支持下列文件格式:BMP、GIF、EXIF、JPG、PNG 和 TIFF

    构造器:

    // 从指定的现有图像初始化 Bitmap 类的新实例
    public Bitmap(Image original)           
    
    // 从指定的数据流初始化 Bitmap 类的新实例
    public Bitmap(Stream stream)            
    
    // 从指定的文件初始化 Bitmap 类的新实例 (filename 位图文件的名称和路径)
    public Bitmap(string filename)          

    注意:在 在释放 Bitmap 之前,此filename 对应的文件将一直保持锁定状态

    常用实例方法:

    1. 获取指定像素的颜色
    public Color GetPixel(int x,int y) 
    参数:
    x : 指定像素的 x 坐标
    y : 指定像素的 y 坐标
    返回值:
    System.Drawing.Color
    
    2. 设置指定像素的颜色
    public void SetPixel(int x,int y,Color color)
    参数:
    x : 指定像素的 x 坐标
    y : 指定像素的 y 坐标
    color: 颜色
    
    3. 将 Bitmap 锁定到系统内存中
    [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    public BitmapData LockBits(Rectangle rect,ImageLockMode flags,PixelFormat format)
    参数:
    rect:  指定要锁定 Bitmap 部分  
    flags: 指定 Bitmap 的访问级别(读/写)
    format: 指定此 Bitmap 的数据格式
    返回值:
    BitmapData  包含有关此锁定操作的信息
    
    4. 从系统内存解锁此 Bitmap
    UnlockBits(BitmapData)
    
    5. 使默认的透明颜色对此 Bitmap 透明
    MakeTransparent() 
    MakeTransparent(Color transparentColor)

    透明化的例子

     1 using System;
     2 using System.Drawing;
     3 
     4 class App
     5 {
     6     static void Main()
     7     {
     8         var img = new Bitmap(@"透明化.png");
     9         img.MakeTransparent();
    10         img.Save(@"透明化_处理后.png")    ;
    11 
    12         // MakeTransparent(Color transparentColor)  对指定Color 也执行透明操作
    13         img.MakeTransparent(Color.FromArgb(0x1364C4));
    14         img.Save(@"透明化_处理后_0x1364C4.png");
    15     }
    16 }
    View Code

    附本小节代码下载

    二、System.Drawing.Imaging.ImageLockMode

    ImageLockMode 枚举:指定传递给 LockBits 方法的标志参数的标志。 LockBits 方法可锁定图像的一部分,以便读取或写入其像素数据

    枚举项:

    ReadOnly:   指定锁定图像的一部分以便读取

    WriteOnly:  指定锁定图像的一部分以便写入

    ReadWrite:  指定锁定图像的一部分以便读取和写入

    三、System.Drawing.Imaging.PixelFormat

    PixelFormat 枚举:指定图像中每个像素的颜色数据的格式

    枚举项:见MSDN

    四、System.Drawing.Imaging.BitmapData

    BitmapData 类:指定位图图像的属性。BitmapData 类由 Bitmap 类的 LockBits 和 UnlockBits 方法使用。 不可继承

    命名空间:   System.Drawing.Imaging

    程序集:   System.Drawing.dll

    继承关系:

    实例属性:

    Height           //获取或设置Bitmap 对象的像素高度,有时也称扫描行数
    Width            //获取或设置Bitmap 对象的像素宽度,这可以看做是一个扫描行中的像素数
    PixelFormat:     //获取或设置此 BitmapData对象的 Bitmap 对象中像素信息的格式
    Scan0            //获取或设置位图中第一个像素数据的地址。它可看成是位图中的第一个扫描行
    Stride           //获取或设置 Bitmap 对象的跨距宽度(也称为扫描宽度)

    五、System.Drawing.Color

    Color 结构:表示一种 ARGB 颜色(alpha、红色、绿色、蓝色)。

    命名空间: System.Drawing

    程序集:   System.Drawing.dll

    静态属性: 各种颜色(如 Color.Red、Color.Yellow 等)

    静态方法:

    Color.FromArgb(int argb)
    例子:
    SolidBrush trnsRedBrush = new SolidBrush(Color.FromArgb(0x78FF0000));
    
    从四个 ARGB 分量(alpha、红色、绿色和蓝色)值创建 Color 结构。 尽管此方法允许为每个分量传递 32 位值,但每个分量的值仅限于 8// 78 FF 00 00
    public static Color FromArgb(int alpha,int red,int green,int blue)

     六、例子 彩色图像简单灰度化

    公式:

    Gray(i,j) = 0.229*R(i,j) + 0.587*G(i,j) + 0.114*B(i,j)

    代码

     1 using System;
     2 using System.Drawing;
     3 using System.Drawing.Imaging;
     4 
     5 class App
     6 {
     7     static void Main()
     8     {
     9         using(var img = new Bitmap(@"BingWallpaper.jpg"))
    10         {
    11             Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
    12             BitmapData bmpData = img.LockBits(rect,ImageLockMode.ReadWrite,img.PixelFormat);
    13             IntPtr ptr = bmpData.Scan0;
    14             int bytes = img.Width * img.Height * 3;
    15             byte[] rgbValues = new byte[bytes];
    16             System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
    17             double colorTemp = 0;
    18             for (int i = 0; i < rgbValues.Length; i += 3)
    19             {
    20                 colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
    21                 rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp;
    22             }
    23             System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
    24             img.UnlockBits(bmpData);
    25             
    26             img.Save(@"BingWallpaper_灰度化.jpg");
    27         }
    28     }
    29 }
    View Code

    附本小节代码下载

    效果

    原图:

    灰度化图:

    2014-12-21 更新:

    1. Format24bppRgb : 每个像素24位,红色、绿色、蓝色分量分别使用8位,它们的顺序是 蓝、率、红(BGR)

    2. Stride 即步幅也称扫描宽度,系统规定它必须是4的倍数

    3. BmpData.Width 与 BmpData.Stride 的关系 BmpData.Stride = BmpData.Width * 3 + X(X为保留字节,用来调节,使Stride 能被4整除)

    下面两幅图说明 Height、 Width 与 Stride

    Scan0

    |
    |---------Stride-----------------|
    |---------Width-------------| |    注:Width是图片(BGR作为一个单位)宽度
    BGR BGR BGR BGR BGR BGR XX
    BGR BGR BGR BGR BGR BGR XX
    .
    .
    注:BGR
    为一个像素,是byte[3]的数组

    下图来自《C#数字图像处理算法》一书

    4. 代码修正

     六、例子 彩色图像简单灰度化 这节的代码有问题,因为我给的图片Width正好是4的倍数,所以 Width *3 也是4的倍数,所以不需要额外字节,但如果Width不是4的倍数,代码就不能得到正确的结果了,下面将修正后的代码贴出

     1 using System;
     2 using System.Drawing;
     3 using System.Drawing.Imaging;
     4 
     5 class App
     6 {
     7     static void Main()
     8     {
     9         using(var img = new Bitmap(@"test.png"))
    10         {
    11             Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
    12             BitmapData bmpData = img.LockBits(rect,ImageLockMode.ReadWrite,img.PixelFormat);
    13             IntPtr ptr = bmpData.Scan0;
    14             
    15             // 用步幅表示
    16             int bytes = bmpData.Stride * bmpData.Height;
    17             byte[] rgbValues = new byte[bytes];
    18             System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
    19             double colorTemp = 0;
    20             int bmpStride = bmpData.Stride;
    21             
    22             for(int bmpheight = 0; bmpheight < bmpData.Height; bmpheight++)
    23             {
    24                 // 只处理实际 Height , 不理会未用空间
    25                 for(int bmpwidth = 0; bmpwidth < bmpData.Width *3; bmpwidth += 3)
    26                 {
    27                     colorTemp = rgbValues[bmpheight * bmpStride + bmpwidth + 2] * 0.299 +
    28                                 rgbValues[bmpheight * bmpStride + bmpwidth + 1] * 0.587 +
    29                                 rgbValues[bmpheight * bmpStride + bmpwidth] * 0.114;
    30                                 
    31                     rgbValues[bmpheight * bmpStride + bmpwidth] = 
    32                     rgbValues[bmpheight * bmpStride + bmpwidth + 1] =
    33                     rgbValues[bmpheight * bmpStride + bmpwidth + 2] = (byte)colorTemp;
    34                 }
    35             }
    36                         
    37             System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
    38             img.UnlockBits(bmpData);
    39             
    40             img.Save(@"BingWallpaper_灰度化.jpg");
    41         }
    42     }
    43 }
    View Code
  • 相关阅读:
    红黑树(RBTree)
    js闭包简要分析
    html 5的localstorag
    浅析CSS中的haslayout
    初识sass框架
    BFC块级格式化上下文简述
    RESTful互联网框架
    javascript的框架演化
    浅析angular框架的cookie
    angular template浅析
  • 原文地址:https://www.cnblogs.com/Aphasia/p/4158827.html
Copyright © 2011-2022 走看看