• [转载] How to convert a colour image to grayscale


    http://www.bobpowell.net/grayscale.htm

    Colours in an image may be converted to a shade of gray by calculating the effective

    brightness or luminance of the colour and using this value to create a shade of gray

    that matches the desired brightness.

    The following code snippet isn't really a good example of how it should be done in a production situation but it does show the principles involved clearly. For every day use. see the ColorMatrix example below.

    The effective luminance of a pixel is calculated with the following formula:

    Y=0.3RED+0.59GREEN+0.11Blue

    This luminance value can then be turned into a grayscale pixel using Color.FromArgb(Y,Y,Y).

    Converting an image from colour to monochrome can be performed using the following code:

    [C#]

    public Bitmap ConvertToGrayscale(Bitmap source)

    {

    Bitmap bm = new Bitmap(source.Width,source.Height);

    for(int y=0;y<bm.Height;y++)

    {

      for(int x=0;x<bm.Width;x++)

      {

        Color c=source.GetPixel(x,y);

        int luma = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);

        bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma));

      }

    }

    return bm;

    }

    [VB]

    Public Function ConvertToGrayscale(ByVal source As Bitmap) as Bitmap

    Dim bm as new Bitmap(source.Width,source.Height)

    Dim x

    Dim y

    For y=0 To bm.Height

      For x=0 To bm.Width

        Dim c as Color = source.GetPixel(x,y)

        Dim luma as Integer = CInt(c.R*0.3 + c.G*0.59 + c.B*0.11)

        bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma)

      Next

    Next

    Return bm

    End Function

    The images below show a color image and its monochrome conversion.

    Alternative Version using the ColorMatrix class

    Jacob Grass ( http://www.windowsforms.net ) sent me an excellent alternative to the

    previous method which uses a colour matrix shear to create the greyscale. While this is

    an effective and quick method of performing the monochrome manipulation, colour

    geeks will tell you that the luminance values are all off and the grey balance of the

    final image is not correct.

    Note: Since I first posted this article, Gilles Khouzam has provided me with a ColorMatrix shear that maintains the luminance correctly. I have placed this matrix definition in the code provided by Jacob and you can see the difference by commenting out one matrix and substituting the other.

    [C#]

    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    namespace GrayShear
    {
      /// <summary>
      /// Summary description for Form1.
      /// </summary>
      public class Form1 : System.Windows.Forms.Form
      {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;
        public Form1()
        {
          //
          // Required for Windows Form Designer support
          //
          InitializeComponent();
          //
          // TODO: Add any constructor code after InitializeComponent call
          //
        }
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
          if( disposing )
          {
            if (components != null) 
            {
              components.Dispose();
            }
          }
          base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
          // 
          // Form1
          // 
          this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
          this.ClientSize = new System.Drawing.Size(296, 269);
          this.Name = "Form1";
          this.Text = "Form1";
          this.Load += new System.EventHandler(this.Form1_Load);
        }
        #endregion
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() 
        {
          Application.Run(new Form1());
        }
        private void Form1_Load(object sender, System.EventArgs e)
        {
          OpenFileDialog dlg = new OpenFileDialog();
          dlg.Filter="Image files (*.BMP, *.JPG, *.GIF)|*.bmp;*.jpg;*.gif";
          if(dlg.ShowDialog()==DialogResult.OK)
          {
            Image img = Image.FromFile(dlg.FileName);
            Bitmap bm = new Bitmap(img.Width,img.Height);
            Graphics g = Graphics.FromImage(bm);
     
            
            ColorMatrix cm = new ColorMatrix(new float[][]{   new float[]{0.5f,0.5f,0.5f,0,0},
                                      new float[]{0.5f,0.5f,0.5f,0,0},
                                      new float[]{0.5f,0.5f,0.5f,0,0},
                                      new float[]{0,0,0,1,0,0},
                                      new float[]{0,0,0,0,1,0},
                                      new float[]{0,0,0,0,0,1}});
            
            /*
            //Gilles Khouzams colour corrected grayscale shear
            ColorMatrix cm = new ColorMatrix(new float[][]{   new float[]{0.3f,0.3f,0.3f,0,0},
                                      new float[]{0.59f,0.59f,0.59f,0,0},
                                      new float[]{0.11f,0.11f,0.11f,0,0},
                                      new float[]{0,0,0,1,0,0},
                                      new float[]{0,0,0,0,1,0},
                                      new float[]{0,0,0,0,0,1}});
            */
            ImageAttributes ia = new ImageAttributes();
            ia.SetColorMatrix(cm);
            g.DrawImage(img,new Rectangle(0,0,img.Width,img.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel,ia);
            g.Dispose();
            this.BackgroundImage=bm;
          }  
        }
      }
    }

    [VB]

    Imports System.Drawing.Imaging
    Public Class Form1
      Inherits System.Windows.Forms.Form
    #Region " Windows Form Designer generated code "
      Public Sub New()
        MyBase.New()
        'This call is required by the Windows Form Designer.
        InitializeComponent()
        'Add any initialization after the InitializeComponent() call
      End Sub
      'Form overrides dispose to clean up the component list.
      Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
          If Not (components Is Nothing) Then
            components.Dispose()
          End If
        End If
        MyBase.Dispose(disposing)
      End Sub
      'Required by the Windows Form Designer
      Private components As System.ComponentModel.IContainer
      'NOTE: The following procedure is required by the Windows Form Designer
      'It can be modified using the Windows Form Designer.  
      'Do not modify it using the code editor.
      <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
        Me.Text = "Form1"
      End Sub
    #End Region
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim dlg As OpenFileDialog = New OpenFileDialog()
        dlg.Filter = "Image files (*.BMP, *.JPG, *.GIF)|*.bmp;*.jpg;*.gif"
        If dlg.ShowDialog() = DialogResult.OK Then
          Dim img As Image = Image.FromFile(dlg.FileName)
          Dim bm As Bitmap = New Bitmap(img.Width, img.Height)
          Dim g As Graphics = Graphics.FromImage(bm)
          Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
               {New Single() {0.5, 0.5, 0.5, 0, 0}, _
              New Single() {0.5, 0.5, 0.5, 0, 0}, _
              New Single() {0.5, 0.5, 0.5, 0, 0}, _
              New Single() {0, 0, 0, 1, 0}, _
              New Single() {0, 0, 0, 0, 1}})
        
        'Gilles Khouzams colour corrected grayscale shear
          'Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
          '     {New Single() {0.3, 0.3, 0.3, 0, 0}, _
          '    New Single() {0.59, 0.59, 0.59, 0, 0}, _
          '    New Single() {0.11, 0.11, 0.11, 0, 0}, _
          '    New Single() {0, 0, 0, 1, 0}, _
          '    New Single() {0, 0, 0, 0, 1}})
          
        Dim ia As ImageAttributes = New ImageAttributes()
          ia.SetColorMatrix(cm)
          g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia)
          g.Dispose()
          Me.BackgroundImage = bm
        End If
      End Sub
    End Class
    

    In conclusion, the technique of turning a colour image into an accurate gray scale is most easily accomplished using the ColorMatrix class initialized with the classic luminance calculation values.

    Back to the GDI+ FAQ

  • 相关阅读:
    法正(17):玄德
    法正(16):舌战
    法正(15):卢氏
    法正(14):寿星
    struts2笔记---struts2的执行过程
    Oracle数据库(一)
    flask的使用(一)
    struts2--笔记(一)
    docker基础(二)
    docker安装及问题处理
  • 原文地址:https://www.cnblogs.com/chinaontology/p/1223216.html
Copyright © 2020-2023  润新知