Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Studio 2015 & .NET 4.6
  4. Faster way to create True B/W Image

Faster way to create True B/W Image

Scheduled Pinned Locked Moved Visual Studio 2015 & .NET 4.6
dotnetgraphicsquestion
5 Posts 3 Posters 14 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    gwittlock
    wrote on last edited by
    #1

    I am using the following code and it does create a B/W image as desired but it seems to be very slow. IS there a better way to do this? Thanks in advance.

        Dim bm As New Bitmap(picCanvas.Image)
        Dim X As Integer
        Dim Y As Integer
        Dim clr As Integer
        Dim r As Integer
        Dim g As Integer
        Dim b As Integer
    
        For X = 0 To bm.Width - 1
            For Y = 0 To bm.Height - 1
                clr = (CInt(bm.GetPixel(X, Y).R) + \_
                       bm.GetPixel(X, Y).G + \_
                       bm.GetPixel(X, Y).B) \\ 3
                bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr))
                r = 255 - bm.GetPixel(X, Y).R
                g = 255 - bm.GetPixel(X, Y).G
                b = 255 - bm.GetPixel(X, Y).B
                bm.SetPixel(X, Y, Color.FromArgb(r, g, b))
            Next Y
        Next X
    
        picCanvas.Image = bm
    
    B Richard DeemingR 2 Replies Last reply
    0
    • G gwittlock

      I am using the following code and it does create a B/W image as desired but it seems to be very slow. IS there a better way to do this? Thanks in advance.

          Dim bm As New Bitmap(picCanvas.Image)
          Dim X As Integer
          Dim Y As Integer
          Dim clr As Integer
          Dim r As Integer
          Dim g As Integer
          Dim b As Integer
      
          For X = 0 To bm.Width - 1
              For Y = 0 To bm.Height - 1
                  clr = (CInt(bm.GetPixel(X, Y).R) + \_
                         bm.GetPixel(X, Y).G + \_
                         bm.GetPixel(X, Y).B) \\ 3
                  bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr))
                  r = 255 - bm.GetPixel(X, Y).R
                  g = 255 - bm.GetPixel(X, Y).G
                  b = 255 - bm.GetPixel(X, Y).B
                  bm.SetPixel(X, Y, Color.FromArgb(r, g, b))
              Next Y
          Next X
      
          picCanvas.Image = bm
      
      B Offline
      B Offline
      Bernhard Hiller
      wrote on last edited by
      #2

      You call bm.GetPixel 6 times with exactly the same X and Y values - do it once only and store the result. Next, you calculate the average of RGB values, set that to the pixel, and call again that GetPixel method, just to substract its value from 255. Do you think the RGB values are different here from each other? Why don't you just substract the average from 255 before the first SetPixel call (and throw away the second half of the method)?

      G 1 Reply Last reply
      0
      • G gwittlock

        I am using the following code and it does create a B/W image as desired but it seems to be very slow. IS there a better way to do this? Thanks in advance.

            Dim bm As New Bitmap(picCanvas.Image)
            Dim X As Integer
            Dim Y As Integer
            Dim clr As Integer
            Dim r As Integer
            Dim g As Integer
            Dim b As Integer
        
            For X = 0 To bm.Width - 1
                For Y = 0 To bm.Height - 1
                    clr = (CInt(bm.GetPixel(X, Y).R) + \_
                           bm.GetPixel(X, Y).G + \_
                           bm.GetPixel(X, Y).B) \\ 3
                    bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr))
                    r = 255 - bm.GetPixel(X, Y).R
                    g = 255 - bm.GetPixel(X, Y).G
                    b = 255 - bm.GetPixel(X, Y).B
                    bm.SetPixel(X, Y, Color.FromArgb(r, g, b))
                Next Y
            Next X
        
            picCanvas.Image = bm
        
        Richard DeemingR Offline
        Richard DeemingR Offline
        Richard Deeming
        wrote on last edited by
        #3

        There are several solutions at: http://tech.pro/tutorial/660/csharp-tutorial-convert-a-color-image-to-grayscale[^] They're in C#, but they should be fairly easy to convert. The simplest method is probably to use a ColorMatrix:

        public static Bitmap MakeGrayscale(Bitmap original)
        {
        Bitmap newBitmap = new Bitmap(original.Width, original.Height);

        using (Graphics g = Graphics.FromImage(newBitmap))
        {
        ColorMatrix colorMatrix = new ColorMatrix(
        new float[][]
        {
        new float[] {.3f, .3f, .3f, 0, 0},
        new float[] {.59f, .59f, .59f, 0, 0},
        new float[] {.11f, .11f, .11f, 0, 0},
        new float[] {0, 0, 0, 1, 0},
        new float[] {0, 0, 0, 0, 1}
        });

          ImageAttributes attributes = new ImageAttributes();
          attributes.SetColorMatrix(colorMatrix);
          
          g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
             0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
        

        }

        return newBitmap;
        }

        Michael Combs posted a good article on the ColorMatrix back in 2003, which includes VB.NET samples: ColorMatrix Basics - Simple Image Color Adjustment[^]


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

        G 1 Reply Last reply
        0
        • B Bernhard Hiller

          You call bm.GetPixel 6 times with exactly the same X and Y values - do it once only and store the result. Next, you calculate the average of RGB values, set that to the pixel, and call again that GetPixel method, just to substract its value from 255. Do you think the RGB values are different here from each other? Why don't you just substract the average from 255 before the first SetPixel call (and throw away the second half of the method)?

          G Offline
          G Offline
          gwittlock
          wrote on last edited by
          #4

          Thanks bernhard that is much faster

          1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            There are several solutions at: http://tech.pro/tutorial/660/csharp-tutorial-convert-a-color-image-to-grayscale[^] They're in C#, but they should be fairly easy to convert. The simplest method is probably to use a ColorMatrix:

            public static Bitmap MakeGrayscale(Bitmap original)
            {
            Bitmap newBitmap = new Bitmap(original.Width, original.Height);

            using (Graphics g = Graphics.FromImage(newBitmap))
            {
            ColorMatrix colorMatrix = new ColorMatrix(
            new float[][]
            {
            new float[] {.3f, .3f, .3f, 0, 0},
            new float[] {.59f, .59f, .59f, 0, 0},
            new float[] {.11f, .11f, .11f, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {0, 0, 0, 0, 1}
            });

              ImageAttributes attributes = new ImageAttributes();
              attributes.SetColorMatrix(colorMatrix);
              
              g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
                 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
            

            }

            return newBitmap;
            }

            Michael Combs posted a good article on the ColorMatrix back in 2003, which includes VB.NET samples: ColorMatrix Basics - Simple Image Color Adjustment[^]


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            G Offline
            G Offline
            gwittlock
            wrote on last edited by
            #5

            Thanks Richard That is pretty fast although I need the black and white inverted. Meaning Black Graphics on White background. but it helps.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups