Click here to Skip to main content
15,885,546 members
Articles / Multimedia / GDI+

Color Scale Filter

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
17 Jul 2007CPOL4 min read 59.7K   2.2K   24  
Grayscale and color scale filters.
' Class implementing grayscale conversion of color image.
' 
' Copyright (c) 2007 Miran Uhan
' 
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program; if not, write to the
'    Free Software Foundation, Inc.
'    51 Franklin Street, Fifth Floor
'    Boston, MA 02110-1301 USA
'
' Sources:
' - http://www.codeproject.com/cs/library/yael_image_filters.asp
' - http://www.bobpowell.net/grayscale.htm
'
' For questions you can contact author at
'    miran.uhan@gmail.com
' Sugestions and bug reports are also welcome.
' 

Imports System.Drawing
Imports System.Drawing.Imaging

Public Class GrayScaleFilter
   Inherits BasicFilter

   Private _brightness As Brightness = Brightness.Normal
   Private _useColorMatrix As Boolean = False
   Private _factorRed As Integer = 30
   Private _factorGreen As Integer = 59
   Private _factorBlue As Integer = 11

   ''' <summary>
   ''' Get or set brightness.
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property Brightness() As Brightness
      Get
         Return _brightness
      End Get
      Set(ByVal value As Brightness)
         _brightness = value
         Select Case _brightness
            Case Brightness.Normal
               _factorRed = 30
               _factorGreen = 59
               _factorBlue = 11
            Case Brightness.Bright
               _factorRed = 50
               _factorGreen = 50
               _factorBlue = 50
         End Select
      End Set
   End Property

   ''' <summary>
   ''' Get or set factor for red component.
   ''' </summary>
   ''' <value>Integer in range [0..100].</value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property FactorRed() As Integer
      Get
         Return _factorRed
      End Get
      Set(ByVal value As Integer)
         If ((value >= 0) And (value <= 100)) Then
            _factorRed = value
         End If
      End Set
   End Property

   ''' <summary>
   ''' Get or set factor for green component.
   ''' </summary>
   ''' <value>Integer in range [0..100].</value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property FactorGreen() As Integer
      Get
         Return _factorGreen
      End Get
      Set(ByVal value As Integer)
         If ((value >= 0) And (value <= 100)) Then
            _factorGreen = value
         End If
      End Set
   End Property

   ''' <summary>
   ''' Get or set factor for blue component.
   ''' </summary>
   ''' <value>Integer in range [0..100].</value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property FactorBlue() As Integer
      Get
         Return _factorBlue
      End Get
      Set(ByVal value As Integer)
         If ((value >= 0) And (value <= 100)) Then
            _factorBlue = value
         End If
      End Set
   End Property

   ''' <summary>
   ''' Get or set color matrix use flag.
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property UseColorMatrix() As Boolean
      Get
         Return _useColorMatrix
      End Get
      Set(ByVal value As Boolean)
         _useColorMatrix = value
      End Set
   End Property

   ''' <summary>
   ''' Execute filter and return filtered image.
   ''' </summary>
   ''' <param name="img"></param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Overrides Function ExecuteFilter( _
            ByVal img As System.Drawing.Image) As System.Drawing.Image
      Select Case img.PixelFormat
         Case PixelFormat.Format16bppGrayScale
            Return img
         Case PixelFormat.Format24bppRgb, _
                  PixelFormat.Format32bppArgb, PixelFormat.Format32bppRgb
            If _useColorMatrix Then
               Return ExecuteRgb8Matrix(img)
            Else
               Return ExecuteRgb8(img)
            End If
         Case PixelFormat.Format48bppRgb
            Return img
         Case Else
            Return img
      End Select
   End Function

   ''' <summary>
   ''' Execute filter on (A)RGB image with 8 bits per color.
   ''' </summary>
   ''' <param name="img"></param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Function ExecuteRgb8( _
            ByVal img As System.Drawing.Image) As System.Drawing.Image
      Dim result As Bitmap = New Bitmap(img)
      Dim bmpData As BitmapData = result.LockBits( _
                     New Rectangle(0, 0, result.Width, result.Height), _
                     ImageLockMode.ReadWrite, img.PixelFormat)
      Dim pixelBytes As Integer = _
               System.Drawing.Image.GetPixelFormatSize(img.PixelFormat) \ 8
      'Get the address of the first line.
      Dim ptr As IntPtr = bmpData.Scan0
      Dim size As Integer = bmpData.Stride * result.Height
      Dim pixels(size - 1) As Byte
      Dim index As Integer
      Dim Y As Integer
      Dim mulR As Double = _factorRed / 100
      Dim mulG As Double = _factorGreen / 100
      Dim mulB As Double = _factorBlue / 100
      'Copy the RGB values into the array.
      System.Runtime.InteropServices.Marshal.Copy(ptr, pixels, 0, size)
      'Main loop.
      For row As Integer = 0 To result.Height - 1
         For col As Integer = 0 To result.Width - 1
            index = (row * bmpData.Stride) + (col * pixelBytes)
            Y = CInt(System.Math.Round( _
                     mulR * pixels(index + 2) + _
                     mulG * pixels(index + 1) + _
                     mulB * pixels(index + 0)))
            If (Y > 255) Then Y = 255
            'Save new values.
            pixels(index + 2) = CByte(Y)
            pixels(index + 1) = CByte(Y)
            pixels(index + 0) = CByte(Y)
         Next
      Next
      'Copy the RGB values back to the bitmap
      System.Runtime.InteropServices.Marshal.Copy(pixels, 0, ptr, size)
      'Unlock the bits.
      result.UnlockBits(bmpData)
      Return result
   End Function

   ''' <summary>
   ''' Execute filter on (A)RGB image with 8 bits per color.
   ''' </summary>
   ''' <param name="img"></param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Function ExecuteRgb8Matrix( _
            ByVal img As System.Drawing.Image) As System.Drawing.Image
      'Reference from http://www.bobpowell.net/grayscale.htm
      Dim result As Bitmap = New Bitmap(img)
      result.SetResolution(img.HorizontalResolution, img.VerticalResolution)
      Dim g As Graphics = Graphics.FromImage(result)
      Dim colorMatrix As ColorMatrix
      If (_brightness) Then
         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} _
                  })
      Else
         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} _
                  })
      End If
      Dim imgAttributes As ImageAttributes = New ImageAttributes()
      imgAttributes.SetColorMatrix(colorMatrix)
      g.DrawImage(result, _
               New Rectangle(0, 0, img.Width, img.Height), _
               0, 0, img.Width, img.Height, _
               GraphicsUnit.Pixel, imgAttributes)
      g.Dispose()
      Return result
   End Function

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
Slovenia Slovenia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions