Link to home
Start Free TrialLog in
Avatar of qetuo088
qetuo088

asked on

Get Pixel in VB

Let say I have a small image, 50 by 10.

How do I use VB to get each individual pixel from my image file, and print each pixel
byte to the screen ?
Avatar of PaulHews
PaulHews
Flag of Canada image

There are different ways to do it.

1.  Load a picbox with picture and use Point and Pset
2.  Load a picbox and use GetPoint, SetPoint API (faster)
3.  If it is a BMP, you can retrieve the individual pixels with the API GetDIBits.

Let me know which way you want to do it.
>2.  Load a picbox and use GetPoint, SetPoint API (faster)

GetPixel, SetPixel is what that should read.
Avatar of qetuo088
qetuo088

ASKER

any sample ?
I think I will use GetDlBits
Avatar of hes
hes,

that example will not work, becaue what I need is a pixel unit. And I can get a byte
that represents the pixel
Here you go.

Option Explicit

Private Type BITMAPFILEHEADER
   bfType As String * 2
   bfSize As Long
   bfReserved1 As Integer
   bfReserved2 As Integer
   bfOffBits As Long
End Type

Private Type RGBQUAD
   rgbBlue As Byte
   rgbGreen As Byte
   rgbRed As Byte
   rgbReserved As Byte
End Type

Private Type BITMAPINFOHEADER
   biSize As Long
   biWidth As Long
   biHeight As Long
   biPlanes As Integer
   biBitCount As Integer
   biCompression As Long
   biSizeImage As Long
   biXPelsPerMeter As Long
   biYPelsPerMeter As Long
   biClrUsed As Long
   biClrImportant As Long
End Type

Private Type BITMAP  '24 bytes
 bmType As Long
 bmWidth As Long
 bmHeight As Long
 bmWidthBytes As Long
 bmPlanes As Integer
 bmBitsPixel As Integer
 bmBits As Long
End Type

Private Type BITMAPINFO
   bmiHeader As BITMAPINFOHEADER
   bmiColors As Long
End Type

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long

Private Declare Function GetDIBits& Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long)
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long

Private Const DIB_RGB_COLORS& = 0
Private Const BI_RGB = 0&




Private Sub Form_Load()
   Dim lngRet As Long
   Dim bih As BITMAPINFO
   Dim hCmpDC As Long
   Dim bmp As BITMAP
   Dim lngW As Long, lngH As Long
   Dim hBMP As Long, hOld As Long
   Dim lngColor() As Long
   Dim BytesPerScanLine As Long
   Dim PadBytesPerScanLine As Long
   Dim pic As StdPicture
   Dim i As Long
'   Dim BFH As BITMAPFILEHEADER  'Size 14






       Set pic = LoadPicture("C:\My Documents\Graphics\BMPs\tslogo3d1.bmp")
       hBMP = pic.Handle
   '    Fill out the BITMAP structure.
       lngRet = GetObject(hBMP, Len(bmp), bmp)
       Debug.Print lngRet
       'Create a device context compatible with the Desktop.
       hCmpDC = CreateCompatibleDC(0&)

       'Select the bitmap handle into the new device context.
       hOld = SelectObject(hCmpDC, hBMP)



   With bih.bmiHeader
       .biSize = 40
       .biWidth = bmp.bmWidth
       .biHeight = bmp.bmHeight
       .biPlanes = 1
       .biBitCount = 32
       .biCompression = BI_RGB
       BytesPerScanLine = ((((.biWidth * .biBitCount) + 31) \ 32) * 4)
       PadBytesPerScanLine = BytesPerScanLine - (((.biWidth * .biBitCount) + 7) \ 8)
       .biSizeImage = BytesPerScanLine * Abs(.biHeight)

 End With


   ReDim lngColor(1 To bmp.bmWidth * bmp.bmHeight)

   lngRet = GetDIBits(hCmpDC, hBMP, 0, bmp.bmHeight, lngColor(1), bih, DIB_RGB_COLORS)
   Debug.Print lngRet

   Picture1.ScaleMode = vbPixels
   Picture1.Width = bmp.bmWidth * Screen.TwipsPerPixelX
   Picture1.Height = bmp.bmHeight * Screen.TwipsPerPixelY
   Picture1.AutoRedraw = True
   Debug.Print bmp.bmHeight, bmp.bmWidth

   'Write pixels one by one
   
    For lngH = bmp.bmHeight - 1 To 0 Step -1
        For lngW = 0 To bmp.bmWidth - 1
            i = i + 1
            SetPixel Picture1.hdc, lngW, lngH, lngColor(i)
           
        Next
    Next





    'Clean up
   SelectObject hCmpDC, hOld
   DeleteObject hBMP
   DeleteDC hCmpDC



End Sub


PaulHews,

You code will make a copy pixel by pixel to picture1, right. But what I want is to print out the byte that represents exach pixel.

For example, here are the first 5 bytes :

 23 4e 3f ff 2e

23 maybe mean blue, ff mean black,  etc.
That's easy enough.  I've shown you how to split the long rgb value into r, g, b components.  You can figure out how to do the printing your own way:

Option Explicit

Private Type BITMAPFILEHEADER
   bfType As String * 2
   bfSize As Long
   bfReserved1 As Integer
   bfReserved2 As Integer
   bfOffBits As Long
End Type

Private Type RGBQUAD
   rgbBlue As Byte
   rgbGreen As Byte
   rgbRed As Byte
   rgbReserved As Byte
End Type

Private Type BITMAPINFOHEADER
   biSize As Long
   biWidth As Long
   biHeight As Long
   biPlanes As Integer
   biBitCount As Integer
   biCompression As Long
   biSizeImage As Long
   biXPelsPerMeter As Long
   biYPelsPerMeter As Long
   biClrUsed As Long
   biClrImportant As Long
End Type

Private Type BITMAP  '24 bytes
 bmType As Long
 bmWidth As Long
 bmHeight As Long
 bmWidthBytes As Long
 bmPlanes As Integer
 bmBitsPixel As Integer
 bmBits As Long
End Type

Private Type BITMAPINFO
   bmiHeader As BITMAPINFOHEADER
   bmiColors As Long
End Type

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long

Private Declare Function GetDIBits& Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long)
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long

Private Const DIB_RGB_COLORS& = 0
Private Const BI_RGB = 0&

Private Type Lng
    Color As Long
End Type

Private Type Byts
    r As Byte
    g As Byte
    b As Byte
    F As Byte
End Type

Private Sub sSplitRGB(lngColour As Long, r As Byte, g As Byte, b As Byte)


    Dim ColourLng As Lng
    Dim RGBByt As Byts
   
    ColourLng.Color = lngColour
   
    LSet RGBByt = ColourLng
   
    r = RGBByt.r
    g = RGBByt.g
    b = RGBByt.b

End Sub


Private Sub Form_Load()
   Dim lngRet As Long
   Dim bih As BITMAPINFO
   Dim hCmpDC As Long
   Dim bmp As BITMAP
   Dim lngW As Long, lngH As Long
   Dim hBMP As Long, hOld As Long
   Dim lngColor() As Long, r As Byte, g As Byte, b As Byte
   Dim BytesPerScanLine As Long
   Dim PadBytesPerScanLine As Long
   Dim pic As StdPicture
   Dim i As Long
'   Dim BFH As BITMAPFILEHEADER  'Size 14






       Set pic = LoadPicture("C:\My Documents\Graphics\BMPs\tslogo3d1.bmp")
       hBMP = pic.Handle
   '    Fill out the BITMAP structure.
       lngRet = GetObject(hBMP, Len(bmp), bmp)
       Debug.Print lngRet
       'Create a device context compatible with the Desktop.
       hCmpDC = CreateCompatibleDC(0&)

       'Select the bitmap handle into the new device context.
       hOld = SelectObject(hCmpDC, hBMP)



   With bih.bmiHeader
       .biSize = 40
       .biWidth = bmp.bmWidth
       .biHeight = bmp.bmHeight
       .biPlanes = 1
       .biBitCount = 32
       .biCompression = BI_RGB
       BytesPerScanLine = ((((.biWidth * .biBitCount) + 31) \ 32) * 4)
       PadBytesPerScanLine = BytesPerScanLine - (((.biWidth * .biBitCount) + 7) \ 8)
       .biSizeImage = BytesPerScanLine * Abs(.biHeight)

 End With


   ReDim lngColor(1 To bmp.bmWidth * bmp.bmHeight)

   lngRet = GetDIBits(hCmpDC, hBMP, 0, bmp.bmHeight, lngColor(1), bih, DIB_RGB_COLORS)
   Debug.Print lngRet

   Picture1.ScaleMode = vbPixels
   Picture1.Width = bmp.bmWidth * Screen.TwipsPerPixelX + 300
   Picture1.Height = bmp.bmHeight * Screen.TwipsPerPixelY + 300
   Picture1.AutoRedraw = True
   Debug.Print bmp.bmHeight, bmp.bmWidth

   'Write pixels one by one
   
    For lngH = bmp.bmHeight - 1 To 0 Step -1
        For lngW = 0 To bmp.bmWidth - 1
            i = i + 1
'            SetPixel Picture1.hdc, lngW, lngH, lngColor(i)
            Call sSplitRGB(lngColor(i), r, g, b)
            Debug.Print "Red : " & Hex(r) & " Green : " & Hex(g) & " Blue : " & Hex(b)
        Next
    Next





    'Clean up
   SelectObject hCmpDC, hOld
   DeleteObject hBMP
   DeleteDC hCmpDC



End Sub


PaulHews,

Why I always got lngColour = -1 ?
Shouldn't I get something like 17234132 ?

And When you use debug.print..., I only see a lot of
duplicate lines :

 Red : ff Green : ff Blue : ff

Why ???
Did you copy and paste the code?  Why don't you send me your test bmp and I'll try it? (email in profile)
It's because your test bitmap is all black and white (mostly white.)  White in RGB is -1 (FF FF FF), black is 0 (00 00 00)

When I ran your bitmap, I got sections like this:

Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : 0 Green : 0 Blue : 0
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : 0 Green : 0 Blue : 0
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : 0 Green : 0 Blue : 0
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF

But mostly FF FF FF (white)
You will get other values than -1 and 0, but that is because there is an unused byte in the long that can contain garbage values.
whooee
PaulHews,

This is what I got :

Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF
Red : FF Green : FF Blue : FF

 33            52

I got all white !
The debug window show more than a few hundred entries (even though over a thousand have been printed.)  Try sending it to a file instead.  Rewrite the pixel writing routine like this:

'Write pixels one by one
    Dim hfile As Integer
    hfile = FreeFile
   
   Open "C:\temp\test.txt" For Output As hfile
   For lngH = bmp.bmHeight - 1 To 0 Step -1
       For lngW = 0 To bmp.bmWidth - 1
           i = i + 1
'            SetPixel Picture1.hdc, lngW, lngH, lngColor(i)
           Call sSplitRGB(lngColor(i), r, g, b)
           Print #hfile, "Red : " & Hex(r) & " Green : " & Hex(g) & " Blue : " & Hex(b)
       Next
   Next
    Close #hfile

Better yet, use a bitmap that has lots of different colors.

I cannot use a lot of color. I am only limited to
Black, grey, lightgrey, white.
Well the file output should work anyway.  Why are you doing all this if you don't mind me asking.  It seems like an unusual way to treat a bitmap.
Let me test it, and I will get back to you !
PaulHews,

I copied the code from Form_Load into a Command1_Click.
When I clicked it, picture1 is empty. Why ?

But after pasted the code back to Form_Load, I could see image in picture1.
ASKER CERTIFIED SOLUTION
Avatar of PaulHews
PaulHews
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial