Click here to Skip to main content
15,886,362 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.8K   2.2K   24  
Grayscale and color scale filters.
' Class implementing color scale 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
'
' 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 ColorScaleFilter
   Inherits BasicFilter

   Private _brightness As Brightness = Brightness.Normal
   Private _red As Integer = 30
   Private _green As Integer = 59
   Private _blue As Integer = 11
   Private _startColor As Color = Color.FromArgb(102, 51, 51)
   Private _endColor As Color = Color.White

   ''' <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
               _red = 30
               _green = 59
               _blue = 11
            Case Brightness.Bright
               _red = 50
               _green = 50
               _blue = 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 _red
      End Get
      Set(ByVal value As Integer)
         If ((value >= 0) And (value <= 100)) Then
            _red = 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 _green
      End Get
      Set(ByVal value As Integer)
         If ((value >= 0) And (value <= 100)) Then
            _green = 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 _blue
      End Get
      Set(ByVal value As Integer)
         If ((value >= 0) And (value <= 100)) Then
            _blue = value
         End If
      End Set
   End Property

   ''' <summary>
   ''' Get or set start color for color scale.
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property StartColor() As Color
      Get
         Return _startColor
      End Get
      Set(ByVal value As Color)
         _startColor = value
      End Set
   End Property

   ''' <summary>
   ''' Get or set end color for color scale.
   ''' </summary>
   ''' <value></value>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Property EndColor() As Color
      Get
         Return _endColor
      End Get
      Set(ByVal value As Color)
         _endColor = 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
            Return ExecuteRgb8(img)
         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 = _red / 100
      Dim mulG As Double = _green / 100
      Dim mulB As Double = _blue / 100
      'Prepare color scale table
      Dim paletteR(255) As Byte
      Dim paletteG(255) As Byte
      Dim paletteB(255) As Byte
      Dim c As Integer
      For i As Integer = 0 To 255
         c = CInt(Math.Round((CDbl(_endColor.R) - CDbl(_startColor.R)) * _
                  CDbl(i) / 255.0 + _startColor.R, 0))
         If c < 0 Then c = 0
         If c > 255 Then c = 255
         paletteR(i) = CByte(c)
         c = CInt(Math.Round((CDbl(_endColor.G) - CDbl(_startColor.G)) * _
                  CDbl(i) / 255.0 + _startColor.G, 0))
         If c < 0 Then c = 0
         If c > 255 Then c = 255
         paletteG(i) = CByte(c)
         c = CInt(Math.Round((CDbl(_endColor.B) - CDbl(_startColor.B)) * _
                  CDbl(i) / 255.0 + _startColor.B, 0))
         If c < 0 Then c = 0
         If c > 255 Then c = 255
         paletteB(i) = CByte(c)
      Next
      '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) = paletteR(Y)
            pixels(index + 1) = paletteG(Y)
            pixels(index + 0) = paletteB(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

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