Results 1 to 8 of 8

Thread: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits

  1. #1

    Thread Starter
    Frenzied Member Jim Davis's Avatar
    Join Date
    Mar 2001
    Location
    Mars base one Username: Jim Davis Password: yCrm33
    Posts
    1,284

    Resolved [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits

    Hello!

    I'm stuck here, i see no reason why i cant properly declare a dc and/or a bitmap object for a b/g/r image data i got from getbitmapbits() api.

    In my theory, this should copy the image from picturebox1 to picturebox2, by converting the picture from picbox1 to a byte array, then reproduces it in a memory bitmap, that i bitblt to the picbox2.

    Code:
    Private Type BITMAP
        bmType As Long
        bmWidth As Long
        bmHeight As Long
        bmWidthBytes As Long
        bmPlanes As Integer
        bmBitsPixel As Integer
        bmBits As Long
    End Type
    
    Private Declare Function DeleteObject Lib "GDI32.dll" (ByVal hObject As Long) As Long
    Private Declare Function SelectObject Lib "GDI32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long
    
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" _
        (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, _
    ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
    ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    
    Private Sub Command1_Click()
    Dim PicArray() As Byte, PicInfo As BITMAP
    Dim hDC As Long, hBMP As Long, hOldBmp As Long
    
      GetObject Picture1.Picture, Len(PicInfo), PicInfo
      ReDim PicArray((PicInfo.bmWidth * PicInfo.bmHeight * (PicInfo.bmBitsPixel / 8)) - 1) As Byte
      GetBitmapBits Picture1.Picture, UBound(PicArray), PicArray(0)
      
      hDC = CreateCompatibleDC(Picture2.hDC)
      hBMP = CreateCompatibleBitmap(Picture2.hDC, PicInfo.bmWidth, PicInfo.bmHeight)
      
      hOldBmp = SelectObject(hDC, hBMP)
      
      Debug.Print SetBitmapBits(hBMP, UBound(PicArray), PicArray(0))
      
      Picture2.Cls
      Debug.Print BitBlt(Picture2.hDC, 0, 0, PicInfo.bmWidth, PicInfo.bmHeight, hDC, 0, 0, vbSrcCopy)
      
      SelectObject hDC, hOldBmp
      DeleteObject hBMP
      DeleteObject hDC
    End Sub
    What i am getting is looks horrible.

    I checked the array to see, what is the array is containing, by using the setpixel. It seems to be the getbitmapbits runs fine, the problem should be around the dc and bitmap creations, but i have no idea why.

    Code:
    Dim PicArray() As Byte, PicInfo As BITMAP
    Dim hDC As Long, hBMP As Long, hOldBmp As Long
    Dim X As Long, Y As Long
    
      GetObject Picture1.Picture, Len(PicInfo), PicInfo
      ReDim PicArray((PicInfo.bmWidth * PicInfo.bmHeight * (PicInfo.bmBitsPixel / 8)) - 1) As Byte
      GetBitmapBits Picture1.Picture, UBound(PicArray), PicArray(0)
      Picture2.Cls
      
      For X = 0 To PicInfo.bmWidth * (PicInfo.bmBitsPixel / 8) Step (PicInfo.bmBitsPixel / 8)
        For Y = 0 To PicInfo.bmHeight - 2
          SetPixel Picture2.hDC, X / 3, Y, RGB(PicArray(Y * ((PicInfo.bmWidth * 3) + 1) + X + 2), PicArray(Y * ((PicInfo.bmWidth * 3) + 1) + X + 1), PicArray(Y * ((PicInfo.bmWidth * 3) + 1) + X + 0))
        Next
      Next

  2. #2
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: How to reproduce image using GetBitmapBits vs SetBitmapBits

    Two small points and a big one

    When calculating the size of a buffer to hold a bitmap you must account for potential scanline padding. Each scanline must always align to a DWord, if the Width * PixelSize is not a multiple of 4 then padding bytes are added. This is not an issue with 32bpp images which always align... Ub = .bmHeight * (.bmWidth * .bmBitsPixel + 31& And -32&) \ 8 - 1

    Seeing as you are using the bitmap structure you can use .bmWidthBytes instead... Ub = .bmWidthbytes * .bmHeight -1

    With the calls you are using for Get/SetBitmapBits you are passing the count wrong, it should be... UBound(PicArray) + 1

    The main reason why it might not work is because CreateCompatibleBitmap is most likely creating a different colour depth bitmap from the one you are trying to set to it. The kind of bitmap it creates is determined by the current desktop colour depth, on my system it creates a 32bpp bitmap. Instead of Get/SetBitmapBits you could try Get/SetDiBits, these let you specify what kind of bitmap you want.

  3. #3

    Thread Starter
    Frenzied Member Jim Davis's Avatar
    Join Date
    Mar 2001
    Location
    Mars base one Username: Jim Davis Password: yCrm33
    Posts
    1,284

    Re: How to reproduce image using GetBitmapBits vs SetBitmapBits

    By using the Get/SetDiBits i got it to work. Thanks for the details, that was i missed!

    vb Code:
    1. Private Declare Function GetDIBits Lib "GDI32.dll" ( _
    2.     ByVal hDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, _
    3.     ByVal nNumScans As Long, ByRef lpBits As Any, _
    4.     ByRef lpBI As BitmapInfo, ByVal wUsage As Long) As Long
    5. Private Declare Function SetDIBits Lib "GDI32.dll" ( _
    6.     ByVal hDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, _
    7.     ByVal nNumScans As Long, ByRef lpBits As Any, _
    8.     ByRef lpBI As BitmapInfo, ByVal wUsage As Long) As Long
    9.  
    10.  Private Type BitmapInfoHeader ' 40 bytes
    11.     biSize As Long
    12.     biWidth As Long
    13.     biHeight As Long
    14.     biPlanes As Integer
    15.     biBitCount As Integer
    16.     biCompression As Long
    17.     biSizeImage As Long
    18.     biXPelsPerMeter As Long
    19.     biYPelsPerMeter As Long
    20.     biClrUsed As Long
    21.     biClrImportant As Long
    22. End Type
    23.  
    24. Private Type BitmapInfo
    25.     bmiHeader As BitmapInfoHeader
    26.     bmiColors(255) As Long
    27. End Type
    28.  
    29. Private Const DIB_RGB_COLORS As Long = 0 ' Colour table in RGBs
    30.  
    31. Private Sub Command2_Click()
    32. Dim DIBInf As BitmapInfo, hDC As Long, hBMP As Long
    33.  
    34.   ' Set the header size
    35.   DIBInf.bmiHeader.biSize = Len(DIBInf.bmiHeader)
    36.  
    37.   hDC = Picture1.hDC
    38.   hBMP = Picture1.Picture.Handle
    39.    
    40.   ' Fill the header structure with information about the Bitmap
    41.   If (GetDIBits(hDC, hBMP, 0, 0, ByVal 0&, DIBInf, DIB_RGB_COLORS)) Then
    42.       ReDim BMData(DIBInf.bmiHeader.biSizeImage - 1) As Byte
    43.       Call GetDIBits(hDC, hBMP, 0, DIBInf.bmiHeader.biHeight, _
    44.           BMData(0), DIBInf, DIB_RGB_COLORS)
    45.  
    46.       hDC = Picture2.hDC
    47.       hBMP = Picture2.Image.Handle
    48.      
    49.       Call SetDIBits(hDC, hBMP, 0, DIBInf.bmiHeader.biHeight, _
    50.           BMData(0), DIBInf, DIB_RGB_COLORS)
    51.   End If
    52.  
    53. End Sub
    Last edited by Jim Davis; Dec 17th, 2008 at 11:14 PM.

  4. #4
    New Member
    Join Date
    Jan 2009
    Posts
    8

    Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits

    Hi,

    I'm trying to do a similar project. I am working in VB.Net 2008 express. I am trying to update a image capture / databasing program that uses VFW and make it compatible with a new USB DirectShow mircoscope. I need to be able to capture a bitmap of a live webcam. To get the image to show up in the preview window I am using Jarno Burger's webcam code found here http://www.codeproject.com/KB/audio-...ctShowNET.aspx

    The only sample code for GetBitmapBIts I could find was in C so I wanted to try to play around with your code to get the screen capture of the webcam. At the moment the errors coming up say that " Picture is not a member of ' System.Windows.Forms.PictureBox' " as well as SetBitMapBits is not declared.
    My ultimate goal is to be able to save the image to a folder on the hard drive where it is added to a database.
    I'm still very new to VB and was hoping you might be able to post the rest of your code so I could see how it starts and try to understand what is going on.

    Thanks,
    Steve

  5. #5
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits

    Hi there, it's VB6 code not Vb.Net

    I would also recommend not using Get/SetBitmapBits, I believe they are just there for backwards compatibility.

    I think VB.Net equivalents of GetDiBits & SetDiBitsToDevice are...
    System.Drawing.Bitmap.LockBits
    System.Drawing.Graphics.DrawImage
    Last edited by Milk; Jan 14th, 2009 at 03:15 PM. Reason: made it a bit clearer

  6. #6
    New Member
    Join Date
    Jan 2009
    Posts
    8

    Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits

    I chose to use GetBitMapBits because my only other option seems to be SampleGrabber. From what I have read SampleGrapher is more complex and MediaDet::GetBitMapBits will work just as well for what I need it to do.

    Thanks for the reply, much appreciated

  7. #7
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits

    I'm pretty sure your best bet is System.Drawing.Bitmap.LockBits.
    GetBitMapBits only still exists for the sake old 16 bit programs. GetDiBits is easier to use and more powerful.

  8. #8
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,238

    Re: How to reproduce image using GetBitmapBits vs SetBitmapBits

    nevermind, this comment was in error
    Last edited by Ben321; Jul 11th, 2012 at 01:03 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width