3 Replies - 3062 Views - Last Post: 07 May 2011 - 07:26 PM Rate Topic: -----

#1 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Lockbits Pointers

Posted 02 May 2011 - 08:30 AM

Hello!

I am processing an image using lockbits and I need to compare pixels with surrounding ones and change them according to the results of the comparison.

My approach is to move simultaneously on two images or bitmapdatas, and make the changes on the second image. This way the changes made won't affect the results of the comparisons on the first one. How do I increase both pointers by the same amount?

The problem I encounter is that I get past the limit of the array bounds. If I manually set the limits to a much smaller amount, I can process the images, but I get a dotted skewed image that shows 3 silhouetes side by side. Something similar to an analog TV set that has the verical and horizontal scans out of synch. I suspect that the pointers are the cause.

Here is my code:

   Private Sub Button8_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
        Dim Tol As Integer = CInt(2.5 * TrackBar2.Value)

        Try
            Dim rect As Rectangle = Rectangle.Round(PictureBox1.Image.GetBounds(GraphicsUnit.Pixel))
            Dim wid As Integer = PictureBox1.Image.Width
            Dim hgt As Integer = PictureBox1.Image.Height
            Dim img As New Bitmap(wid, hgt)
            img = WorkImg
            Dim img1 As New Bitmap(wid, hgt)
            img1 = PictureBox1.Image 'WorkImg
            Dim bmpSr As BitmapData = img.LockBits(New Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, img.PixelFormat)
            Dim bmpRes As BitmapData = img1.LockBits(New Rectangle(0, 0, img1.Width, img1.Height), ImageLockMode.ReadWrite, img1.PixelFormat)

            Dim ptrSr As IntPtr = bmpSr.Scan0
            Dim ptrRes As IntPtr = bmpRes.Scan0
            Dim R, G, B As Integer
            R = 1
            G = 2
            B = 3
            Dim bytesSr As Integer = bmpSr.Stride * img.Height
            Dim bytesRes As Integer = bmpRes.Stride * img1.Height
            Dim rgbvaluesSr(bytesSr) As Byte
            Dim rgbvaluesRes(bytesRes) As Byte
            System.Runtime.InteropServices.Marshal.Copy(ptrSr, rgbvaluesSr, 0, bytesSr)
            System.Runtime.InteropServices.Marshal.Copy(ptrRes, rgbvaluesRes, 0, bytesRes)
            For i As Integer = (bmpSr.Stride - 1) To img.Width * (img.Height - 20) Step 4 'Here Hardcoded values to test

                If (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B)/>) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B)/>)) > NBlue.Value Or _
                     (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + R + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + R + bmpSr.Stride))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + G + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + G + bmpSr.Stride))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + B + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + B + bmpSr.Stride))) > NBlue.Value Or _
                     (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R + bmpSr.Stride))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G + bmpSr.Stride))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B + bmpSr.Stride))) > NBlue.Value Or _
                     (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R - bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R - bmpSr.Stride))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G - bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G - bmpSr.Stride))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B - bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B - bmpSr.Stride))) > NBlue.Value Or _
                     (CInt(rgbvaluesSr(i + R) / 3 + rgbvaluesSr(i + G) / 3 + rgbvaluesSr(i + B)/> / 3) - CInt(rgbvaluesSr(i + 4 + R) / 3 + rgbvaluesSr(i + 4 + G) / 3 + rgbvaluesSr(i + 4 + B)/>) / 3) = Tol Or _
                     (CInt(rgbvaluesSr(i + R) / 3 + rgbvaluesSr(i + G) / 3 + rgbvaluesSr(i + B)/> / 3) - CInt(rgbvaluesSr(i + 4 + R + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + G + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + B + bmpSr.Stride) / 3) = Tol Or _
                     (CInt(rgbvaluesSr(i + R) / 3 + rgbvaluesSr(i + G) / 3 + rgbvaluesSr(i + B)/> / 3) - CInt(rgbvaluesSr(i + 4 + R + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + G + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + B + bmpSr.Stride) / 3) = Tol)) Then

                    rgbvaluesRes(i) = 255
                    rgbvaluesRes(i + R) = 0
                    rgbvaluesRes(i + G) = 0
                    rgbvaluesRes(i + B)/> = 0
                Else
                    rgbvaluesRes(i) = 255
                    rgbvaluesRes(i + R) = 255
                    rgbvaluesRes(i + G) = 255
                    rgbvaluesRes(i + B)/> = 255

                End If
            Next
            System.Runtime.InteropServices.Marshal.Copy(rgbvaluesRes, 1000, ptrRes, bytesRes)'Here Harcoded value to test

            img.UnlockBits(bmpSr)
            img1.UnlockBits(bmpSr)
            PictureBox1.Image = img1
            PictureBox1.Invalidate()
            Dim bmpFromImage As New Bitmap(PictureBox1.Width, PictureBox1.Height)
            bmpFromImage = PictureBox1.Image
            Dim g1 As Graphics = Graphics.FromImage(img1)
            g1.DrawImage(bmpFromImage, 0, 0, img1.Width, img1.Height)
            g1.Dispose()
        Catch ex As Exception
            MessageBox.Show("NoImage To Process")
        End Try
    End Sub


I have a similar subroutine with only one image, but it won't detect slanted down lines, so I want to compare pixels with the ones above to the right.

I am just starting to figure out Lockbits and I don't know how to go about it. Any directions on this regard will be really appreciated.

Regards,

ricardosms

This post has been edited by ricardosms: 02 May 2011 - 08:32 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Lockbits Pointers

#2 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Re: Lockbits Pointers

Posted 02 May 2011 - 04:25 PM

OK! Guys:

I found the problem.
Actually there were two problems: Using WorkImg was giving me the problem that it was already locked, so I used the image on picturebox one without noticing that the byte arrays were different in lenght. One was 3/4 of the other, so i figured out that one was Format24bppRgb and the other Format32bppArgb. That was why I was going out of bounds. So I solved the problem by clonning WorkImg. It seems that I didn't actually have two images. I only had two pointers to the same image. So now I have:

        Try
            Dim rect As Rectangle = Rectangle.Round(PictureBox1.Image.GetBounds(GraphicsUnit.Pixel))
            Dim wid As Integer = PictureBox1.Image.Width
            Dim hgt As Integer = PictureBox1.Image.Height
            Dim img As New Bitmap(wid, hgt)
            img = WorkImg
            Dim img1 As New Bitmap(wid, hgt)
            img1 = WorkImg.Clone
            Dim bmpSr As BitmapData = img.LockBits(New Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, img.PixelFormat)
            Dim bmpRes As BitmapData = img1.LockBits(New Rectangle(0, 0, img1.Width, img1.Height), ImageLockMode.ReadWrite, img1.PixelFormat)

            Dim ptrSr As IntPtr = bmpSr.Scan0
            Dim ptrRes As IntPtr = bmpRes.Scan0
            Dim R, G, B As Integer
            R = 1
            G = 2
            B = 3
            Dim bytesSr As Integer = bmpSr.Stride * img.Height
            Dim bytesRes As Integer = bmpRes.Stride * img1.Height
            Dim rgbvaluesSr(bytesSr) As Byte
            Dim rgbvaluesRes(bytesRes) As Byte
            System.Runtime.InteropServices.Marshal.Copy(ptrSr, rgbvaluesSr, 0, bytesSr)
            System.Runtime.InteropServices.Marshal.Copy(ptrRes, rgbvaluesRes, 0, bytesRes)
            For i As Integer = (bmpSr.Stride - 1) To rgbvaluesSr.Length - bmpSr.Stride - 8 Step 4

                If (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B)/>) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B)/>)) > NBlue.Value Or _
                     (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + R + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + R + bmpSr.Stride))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + G + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + G + bmpSr.Stride))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + B + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + B + bmpSr.Stride))) > NBlue.Value Or _
                     (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R + bmpSr.Stride))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G + bmpSr.Stride))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B + bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B + bmpSr.Stride))) > NBlue.Value Or _
                     (Math.Max(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R - bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + R), rgbvaluesSr(i + 4 + R - bmpSr.Stride))) > NRed.Value Or _
                     (Math.Max(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G - bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + G), rgbvaluesSr(i + 4 + G - bmpSr.Stride))) > NGreen.Value Or _
                     (Math.Max(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B - bmpSr.Stride)) - Math.Min(rgbvaluesSr(i + B)/>, rgbvaluesSr(i + 4 + B - bmpSr.Stride))) > NBlue.Value Or _
                     (CInt(rgbvaluesSr(i + R) / 3 + rgbvaluesSr(i + G) / 3 + rgbvaluesSr(i + B)/> / 3) - CInt(rgbvaluesSr(i + 4 + R) / 3 + rgbvaluesSr(i + 4 + G) / 3 + rgbvaluesSr(i + 4 + B)/>) / 3) = Tol Or _
                     (CInt(rgbvaluesSr(i + R) / 3 + rgbvaluesSr(i + G) / 3 + rgbvaluesSr(i + B)/> / 3) - CInt(rgbvaluesSr(i + 4 + R + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + G + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + B + bmpSr.Stride) / 3) = Tol Or _
                     (CInt(rgbvaluesSr(i + R) / 3 + rgbvaluesSr(i + G) / 3 + rgbvaluesSr(i + B)/> / 3) - CInt(rgbvaluesSr(i + 4 + R + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + G + bmpSr.Stride) / 3 + rgbvaluesSr(i + 4 + B + bmpSr.Stride) / 3) = Tol)) Then

                    rgbvaluesRes(i) = 255
                    rgbvaluesRes(i + R) = 0
                    rgbvaluesRes(i + G) = 0
                    rgbvaluesRes(i + B)/> = 0
                Else
                    rgbvaluesRes(i) = 255
                    rgbvaluesRes(i + R) = 255
                    rgbvaluesRes(i + G) = 255
                    rgbvaluesRes(i + B)/> = 255

                End If
            Next
            System.Runtime.InteropServices.Marshal.Copy(rgbvaluesRes, 0, ptrRes, bytesSr)

            img.UnlockBits(bmpSr)
            img1.UnlockBits(bmpSr)
            PictureBox1.Image = img1
            PictureBox1.Invalidate()
            Dim bmpFromImage As New Bitmap(PictureBox1.Width, PictureBox1.Height)
            bmpFromImage = PictureBox1.Image
            Dim g1 As Graphics = Graphics.FromImage(img1)
            g1.DrawImage(bmpFromImage, 0, 0, img1.Width, img1.Height)
            g1.Dispose()
        Catch ex As Exception
            ' MessageBox.Show("NoImage To Process")
            MessageBox.Show(ex.ToString)
        End Try



I still need to adjust the first and last lines, but that is minor.

Thank you.
Regards,

ricardosms
Was This Post Helpful? 1
  • +
  • -

#3 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Re: Lockbits Pointers

Posted 07 May 2011 - 06:11 PM

OK
Just elaborting a little bit more. Net stores internally the images as Format32bppArgb.
If you load an image from file:

PictureBox1.Image = Image.FromFile("C:\Junk\MyPicture.Jpg")


If MyPicture.Jpg was a Format24bppRgb image, Picturebox1.Image will also be a Format24bppRgb image, but as soon as you apply to it a colormatrix, it becomes a Format32bppArgb image. So be carefull and manipulate it accordingly.

Here is a Scrren shot:


Attached image(s)

  • Attached Image

Was This Post Helpful? 1
  • +
  • -

#4 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1064
  • View blog
  • Posts: 4,167
  • Joined: 02-July 08

Re: Lockbits Pointers

Posted 07 May 2011 - 07:26 PM

Thanks for sharing!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1