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
  • 相关阅读:
    POJ1486 Sorting Slides 二分图or贪心
    POJ2060 Taxi Cab Scheme 最小路径覆盖
    POJ3083 Children of the Candy Corn 解题报告
    以前的文章
    POJ2449 Remmarguts' Date K短路经典题
    这一年的acm路
    POJ3014 Asteroids 最小点覆盖
    POJ2594 Treasure Exploration 最小路径覆盖
    POJ3009 Curling 2.0 解题报告
    POJ2226 Muddy Fields 最小点集覆盖
  • 原文地址:https://www.cnblogs.com/Aphasia/p/4158827.html
Copyright © 2011-2022 走看看